From d8b0a130f10d724b409ad25c44c36d05405486e9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sat, 2 Jul 2022 10:09:25 +0200 Subject: [PATCH 001/111] Minor documentation changes --- Library/Homebrew/livecheck.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck.rb b/Library/Homebrew/livecheck.rb index 52a76e8425..3098673d66 100644 --- a/Library/Homebrew/livecheck.rb +++ b/Library/Homebrew/livecheck.rb @@ -1,7 +1,7 @@ # typed: true # frozen_string_literal: true -# The {Livecheck} class implements the DSL methods used in a formula's or cask's +# The {Livecheck} class implements the DSL methods used in a formula's, cask's or resource's # `livecheck` block and stores related instance variables. Most of these methods # also return the related instance variable when no argument is provided. # @@ -11,13 +11,13 @@ class Livecheck extend Forwardable - # A very brief description of why the formula/cask is skipped (e.g. `No longer + # A very brief description of why the formula/cask/resource is skipped (e.g. `No longer # developed or maintained`). # @return [String, nil] attr_reader :skip_msg - def initialize(formula_or_cask) - @formula_or_cask = formula_or_cask + def initialize(package_or_resource) + @package_or_resource = package_or_resource @referenced_cask_name = nil @referenced_formula_name = nil @regex = nil From e1098765f64662b5bca40fd5e1d36de4827afacb Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sat, 2 Jul 2022 10:20:11 +0200 Subject: [PATCH 002/111] Minor fix for `brew style` --- Library/Homebrew/test/resource_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/test/resource_spec.rb b/Library/Homebrew/test/resource_spec.rb index 9758b376b9..ed34c294ed 100644 --- a/Library/Homebrew/test/resource_spec.rb +++ b/Library/Homebrew/test/resource_spec.rb @@ -6,7 +6,7 @@ require "livecheck" describe Resource do subject(:resource) { described_class.new("test") } - + let(:livecheck_resource) { described_class.new do url "https://brew.sh/test-0.0.1.tgz" From 04981d5387d97956101f85b69edc6cf87368c899 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sat, 2 Jul 2022 10:09:25 +0200 Subject: [PATCH 003/111] Minor documentation changes --- Library/Homebrew/livecheck.rb | 26 ++++++++++++++------------ Library/Homebrew/test/resource_spec.rb | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Library/Homebrew/livecheck.rb b/Library/Homebrew/livecheck.rb index 52a76e8425..66abd5142f 100644 --- a/Library/Homebrew/livecheck.rb +++ b/Library/Homebrew/livecheck.rb @@ -1,9 +1,10 @@ # typed: true # frozen_string_literal: true -# The {Livecheck} class implements the DSL methods used in a formula's or cask's -# `livecheck` block and stores related instance variables. Most of these methods -# also return the related instance variable when no argument is provided. +# The {Livecheck} class implements the DSL methods used in a formula's, cask's +# or resource's `livecheck` block and stores related instance variables. Most +# of these methods also return the related instance variable when no argument +# is provided. # # This information is used by the `brew livecheck` command to control its # behavior. Example `livecheck` blocks can be found in the @@ -11,13 +12,13 @@ class Livecheck extend Forwardable - # A very brief description of why the formula/cask is skipped (e.g. `No longer - # developed or maintained`). + # A very brief description of why the formula/cask/resource is skipped (e.g. + # `No longer developed or maintained`). # @return [String, nil] attr_reader :skip_msg - def initialize(formula_or_cask) - @formula_or_cask = formula_or_cask + def initialize(package_or_resource) + @package_or_resource = package_or_resource @referenced_cask_name = nil @referenced_formula_name = nil @regex = nil @@ -81,8 +82,9 @@ class Livecheck # Sets the `@skip` instance variable to `true` and sets the `@skip_msg` # instance variable if a `String` is provided. `@skip` is used to indicate - # that the formula/cask should be skipped and the `skip_msg` very briefly - # describes why it is skipped (e.g. "No longer developed or maintained"). + # that the formula/cask/resource should be skipped and the `skip_msg` very + # briefly describes why it is skipped (e.g. "No longer developed or + # maintained"). # # @param skip_msg [String] string describing why the formula/cask is skipped # @return [Boolean] @@ -96,7 +98,7 @@ class Livecheck @skip = true end - # Should `livecheck` skip this formula/cask? + # Should `livecheck` skip this formula/cask/resource? def skip? @skip end @@ -126,7 +128,7 @@ class Livecheck # Sets the `@url` instance variable to the provided argument or returns the # `@url` instance variable when no argument is provided. The argument can be # a `String` (a URL) or a supported `Symbol` corresponding to a URL in the - # formula/cask (e.g. `:stable`, `:homepage`, `:head`, `:url`). + # formula/cask/resource (e.g. `:stable`, `:homepage`, `:head`, `:url`). # @param val [String, Symbol] URL to check for version information # @return [String, nil] def url(val = nil) @@ -140,7 +142,7 @@ class Livecheck end end - delegate version: :@formula_or_cask + delegate version: :@package_or_resource private :version # Returns a `Hash` of all instance variable values. diff --git a/Library/Homebrew/test/resource_spec.rb b/Library/Homebrew/test/resource_spec.rb index 9758b376b9..ed34c294ed 100644 --- a/Library/Homebrew/test/resource_spec.rb +++ b/Library/Homebrew/test/resource_spec.rb @@ -6,7 +6,7 @@ require "livecheck" describe Resource do subject(:resource) { described_class.new("test") } - + let(:livecheck_resource) { described_class.new do url "https://brew.sh/test-0.0.1.tgz" From 7156c95b825c79b4e42ffe8f3ab4cea8a6bee402 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 17 Jul 2022 12:45:29 +0200 Subject: [PATCH 004/111] Added `--resources` option in livecheck cmd --- Library/Homebrew/dev-cmd/livecheck.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 0028cc83aa..c183656fda 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -35,6 +35,8 @@ module Homebrew description: "Show the latest version only if it's newer than the formula/cask." switch "--json", description: "Output information in JSON format." + switch "-r", "--resources", + description: "Check resources with livecheck blocks." switch "-q", "--quiet", description: "Suppress warnings, don't print a progress bar for JSON output." switch "--formula", "--formulae", From 59165ed3ec78466b0536f347dcbeb60cde7587cc Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 17 Jul 2022 12:47:20 +0200 Subject: [PATCH 005/111] Get all resources in all formulae --- Library/Homebrew/dev-cmd/livecheck.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index c183656fda..29541377df 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -69,6 +69,14 @@ module Homebrew formulae = args.cask? ? [] : Formula.installed casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks + elsif args.resources? + resources = Formula.all do |formula| + formula.resources.any do |resource| + if resource.livecheckable? + p resource + end + end + end elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all @@ -95,6 +103,11 @@ module Homebrew else raise UsageError, "A watchlist file is required when no arguments are given." end + p formulae_and_casks_to_check.class + p formulae_and_casks_to_check.length + p formulae_and_casks_to_check[0].class + p formulae_and_casks_to_check[0] + formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name end @@ -111,6 +124,6 @@ module Homebrew verbose: args.verbose?, }.compact - Livecheck.run_checks(formulae_and_casks_to_check, **options) + # Livecheck.run_checks(formulae_and_casks_to_check, **options) end end From 8ef6118ba06a5ae45b11681829cd925e424f92a8 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 17 Jul 2022 13:02:22 +0200 Subject: [PATCH 006/111] Work in progress: Fetch all resources with livecheck block --- Library/Homebrew/dev-cmd/livecheck.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 29541377df..bd2e177211 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -73,10 +73,12 @@ module Homebrew resources = Formula.all do |formula| formula.resources.any do |resource| if resource.livecheckable? - p resource + resource end end + # formula.resources.filter? { |resource| !resource.livecheckable? } end + resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all From dba5754c9fbd44611f80d50380a29de1e60b43df Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:03:40 +0200 Subject: [PATCH 007/111] Filter out resources with livecheck block: Work in progress --- Library/Homebrew/dev-cmd/livecheck.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index bd2e177211..29a08e44d6 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,8 +70,9 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - resources = Formula.all do |formula| - formula.resources.any do |resource| + formulae = Formula.all + resources = formulae do |formula| + formula.resources.each do |resource| if resource.livecheckable? resource end @@ -105,6 +106,7 @@ module Homebrew else raise UsageError, "A watchlist file is required when no arguments are given." end + p formulae_and_casks_to_check.class p formulae_and_casks_to_check.length p formulae_and_casks_to_check[0].class From ad1a9b5970fd9186b40aa0ba2ffe0582b319f6d5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:07:33 +0200 Subject: [PATCH 008/111] Fetched all formulas with livecheckable resources --- Library/Homebrew/dev-cmd/livecheck.rb | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 29a08e44d6..e8fa8bfcb4 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,16 +70,8 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - formulae = Formula.all - resources = formulae do |formula| - formula.resources.each do |resource| - if resource.livecheckable? - resource - end - end - # formula.resources.filter? { |resource| !resource.livecheckable? } - end - resources + livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } + livecheckable_resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all From 82057003a7b548346291eb55d127617e35306289 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:36:27 +0200 Subject: [PATCH 009/111] Selected all formulas with livecheckable resources --- Library/Homebrew/dev-cmd/livecheck.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index e8fa8bfcb4..c38f5be411 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,7 +70,9 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } + formula_with_livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } + livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources } + # livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources.filter { |resource| resource.livecheckable? } } livecheckable_resources elsif args.all? formulae = args.cask? ? [] : Formula.all From f8320c89edf5c416cfe4ac88ad102177b519c4ac Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:42:43 +0200 Subject: [PATCH 010/111] Selected all livecheckable resources --- Library/Homebrew/dev-cmd/livecheck.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index c38f5be411..c34ef48b7d 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -71,8 +71,7 @@ module Homebrew formulae + casks elsif args.resources? formula_with_livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } - livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources } - # livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources.filter { |resource| resource.livecheckable? } } + livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources }.flatten.filter{ |resource| resource.livecheckable? } livecheckable_resources elsif args.all? formulae = args.cask? ? [] : Formula.all @@ -104,7 +103,7 @@ module Homebrew p formulae_and_casks_to_check.class p formulae_and_casks_to_check.length p formulae_and_casks_to_check[0].class - p formulae_and_casks_to_check[0] + # p formulae_and_casks_to_check[0] formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name From 2d231a34785d9e452f2ba7f80b4f536c924eb782 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:49:32 +0200 Subject: [PATCH 011/111] More compact way to get livecheckable resources --- .gitignore | 2 +- .vscode/settings.json | 4 +++- Library/Homebrew/dev-cmd/livecheck.rb | 5 ++--- Library/Taps/homebrew/homebrew-core | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) create mode 160000 Library/Taps/homebrew/homebrew-core diff --git a/.gitignore b/.gitignore index 8f52acf25c..76d5c48355 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ /Library/Homebrew/test/junit /Library/Homebrew/test/fs_leak_log /Library/Homebrew/vendor/portable-ruby -/Library/Taps +#/Library/Taps /Library/PinnedTaps /Library/Homebrew/.byebug_history /Library/Homebrew/sorbet/rbi/hidden-definitions/errors.txt diff --git a/.vscode/settings.json b/.vscode/settings.json index 865fc53af2..fe8a066e21 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,5 +23,7 @@ "editor.codeActionsOnSave": { "source.fixAll.shellcheck": true, } - } + }, + "git.mergeEditor": true, + "merge-conflict.autoNavigateNextConflict.enabled": true } diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index c34ef48b7d..ff1bbfa65b 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,8 +70,7 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - formula_with_livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } - livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources }.flatten.filter{ |resource| resource.livecheckable? } + livecheckable_resources = Formula.all.map { |formula| formula.resources }.flatten.filter{ |resource| resource.livecheckable? } livecheckable_resources elsif args.all? formulae = args.cask? ? [] : Formula.all @@ -121,6 +120,6 @@ module Homebrew verbose: args.verbose?, }.compact - # Livecheck.run_checks(formulae_and_casks_to_check, **options) + Livecheck.run_checks(formulae_and_casks_to_check, **options) end end diff --git a/Library/Taps/homebrew/homebrew-core b/Library/Taps/homebrew/homebrew-core new file mode 160000 index 0000000000..88b2623dd6 --- /dev/null +++ b/Library/Taps/homebrew/homebrew-core @@ -0,0 +1 @@ +Subproject commit 88b2623dd6ff0dec391029b1f43107438935f4b7 From 4aa3cc6c972b681aa22f03ab719a9a98ad3ae7d9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 15:03:05 +0200 Subject: [PATCH 012/111] Minor --- Library/Homebrew/dev-cmd/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index ff1bbfa65b..84b9c24a70 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -102,7 +102,7 @@ module Homebrew p formulae_and_casks_to_check.class p formulae_and_casks_to_check.length p formulae_and_casks_to_check[0].class - # p formulae_and_casks_to_check[0] + p formulae_and_casks_to_check.map { |d| d.name } formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name @@ -120,6 +120,6 @@ module Homebrew verbose: args.verbose?, }.compact - Livecheck.run_checks(formulae_and_casks_to_check, **options) + # Livecheck.run_checks(formulae_and_casks_to_check, **options) end end From 0ee69e2c6351aa8f1dc0e2bcba3c084e7b5e5825 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 21 Jul 2022 20:02:15 +0200 Subject: [PATCH 013/111] Refractoring for livecheckable resources --- Library/Homebrew/dev-cmd/livecheck.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 84b9c24a70..41e8b6e8ff 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -60,7 +60,7 @@ module Homebrew puts Homebrew::EnvConfig.livecheck_watchlist if Homebrew::EnvConfig.livecheck_watchlist.present? end - formulae_and_casks_to_check = if args.tap + package_and_resource_to_check = if args.tap tap = Tap.fetch(args.tap) formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) } casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) } @@ -82,7 +82,7 @@ module Homebrew elsif args.cask? args.named.to_casks else - args.named.to_formulae_and_casks + args.named.to_package_and_resource end elsif File.exist?(WATCHLIST_PATH) begin @@ -91,7 +91,7 @@ module Homebrew .map(&:strip) named_args = T.unsafe(CLI::NamedArgs).new(*names, parent: args) - named_args.to_formulae_and_casks(ignore_unavailable: true) + named_args.to_package_and_resource(ignore_unavailable: true) rescue Errno::ENOENT => e onoe e end @@ -99,16 +99,16 @@ module Homebrew raise UsageError, "A watchlist file is required when no arguments are given." end - p formulae_and_casks_to_check.class - p formulae_and_casks_to_check.length - p formulae_and_casks_to_check[0].class - p formulae_and_casks_to_check.map { |d| d.name } + p package_and_resource_to_check.class + p package_and_resource_to_check.length + p package_and_resource_to_check[0].class + p package_and_resource_to_check.map { |d| d.name } - formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| - formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name + package_and_resource_to_check = package_and_resource_to_check.sort_by do |package_or_resource| + package_or_resource.respond_to?(:token) ? package_or_resource.token : package_or_resource.name end - raise UsageError, "No formulae or casks to check." if formulae_and_casks_to_check.blank? + raise UsageError, "No formulae or casks to check." if package_and_resource_to_check.blank? options = { json: args.json?, @@ -120,6 +120,6 @@ module Homebrew verbose: args.verbose?, }.compact - # Livecheck.run_checks(formulae_and_casks_to_check, **options) + Livecheck.run_checks(package_and_resource_to_check[1..3], **options) end end From 7575170a0b63c0cb05f43580500a95fd1a332c4a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 21 Jul 2022 20:02:54 +0200 Subject: [PATCH 014/111] Work in progress for livecheckable resources --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bdc25c3371..50f4229385 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -159,7 +159,7 @@ module Homebrew # `formulae_and_casks_to_check` array and prints the results. sig { params( - formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], + formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask, Resource)], full_name: T::Boolean, handle_name_conflict: T::Boolean, json: T::Boolean, From ebf52091eb372171f529aff3324b6eb3af59c9c5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 14:14:10 +0200 Subject: [PATCH 015/111] Check only formulas with resources --- Library/Homebrew/dev-cmd/livecheck.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 41e8b6e8ff..6c55f7e8d3 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,8 +70,8 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - livecheckable_resources = Formula.all.map { |formula| formula.resources }.flatten.filter{ |resource| resource.livecheckable? } - livecheckable_resources + formula_with_resources = Formula.all.select { |formula| formula.resources.any? } + formula_with_resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all @@ -99,10 +99,10 @@ module Homebrew raise UsageError, "A watchlist file is required when no arguments are given." end - p package_and_resource_to_check.class - p package_and_resource_to_check.length - p package_and_resource_to_check[0].class - p package_and_resource_to_check.map { |d| d.name } + # p package_and_resource_to_check.class + # p package_and_resource_to_check.length + # p package_and_resource_to_check[0].class + # p package_and_resource_to_check.map { |d| d.name } package_and_resource_to_check = package_and_resource_to_check.sort_by do |package_or_resource| package_or_resource.respond_to?(:token) ? package_or_resource.token : package_or_resource.name From 9708a850d98b6f53f59dd6cea52d6c5994a7192a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 14:15:38 +0200 Subject: [PATCH 016/111] Merged with master --- .../lib/sorbet-runtime.rb | 116 ++ .../lib/types/_types.rb | 316 +++++ .../lib/types/abstract_utils.rb | 50 + .../lib/types/boolean.rb | 8 + .../lib/types/compatibility_patches.rb | 93 ++ .../lib/types/configuration.rb | 591 ++++++++ .../lib/types/enum.rb | 377 ++++++ .../lib/types/generic.rb | 22 + .../lib/types/helpers.rb | 58 + .../lib/types/interface_wrapper.rb | 158 +++ .../lib/types/non_forcing_constants.rb | 65 + .../lib/types/private/abstract/data.rb | 36 + .../lib/types/private/abstract/declare.rb | 53 + .../lib/types/private/abstract/hooks.rb | 42 + .../lib/types/private/abstract/validate.rb | 128 ++ .../lib/types/private/casts.rb | 41 + .../lib/types/private/class_utils.rb | 110 ++ .../lib/types/private/compiler.rb | 24 + .../lib/types/private/decl_state.rb | 30 + .../lib/types/private/final.rb | 50 + .../lib/types/private/methods/_methods.rb | 581 ++++++++ .../types/private/methods/call_validation.rb | 221 +++ .../private/methods/call_validation_2_6.rb | 1203 +++++++++++++++++ .../private/methods/call_validation_2_7.rb | 1203 +++++++++++++++++ .../lib/types/private/methods/decl_builder.rb | 232 ++++ .../lib/types/private/methods/modes.rb | 28 + .../lib/types/private/methods/signature.rb | 225 +++ .../private/methods/signature_validation.rb | 225 +++ .../lib/types/private/mixins/mixins.rb | 27 + .../lib/types/private/retry.rb | 10 + .../lib/types/private/runtime_levels.rb | 62 + .../lib/types/private/sealed.rb | 91 ++ .../lib/types/private/types/not_typed.rb | 23 + .../lib/types/private/types/string_holder.rb | 26 + .../lib/types/private/types/type_alias.rb | 31 + .../lib/types/private/types/void.rb | 34 + .../lib/types/props/_props.rb | 169 +++ .../lib/types/props/constructor.rb | 40 + .../lib/types/props/custom_type.rb | 108 ++ .../lib/types/props/decorator.rb | 669 +++++++++ .../lib/types/props/errors.rb | 8 + .../types/props/generated_code_validation.rb | 277 ++++ .../props/has_lazily_specialized_methods.rb | 140 ++ .../lib/types/props/optional.rb | 89 ++ .../lib/types/props/plugin.rb | 37 + .../lib/types/props/pretty_printable.rb | 107 ++ .../lib/types/props/private/apply_default.rb | 170 +++ .../props/private/deserializer_generator.rb | 160 +++ .../lib/types/props/private/parser.rb | 32 + .../types/props/private/serde_transform.rb | 186 +++ .../props/private/serializer_generator.rb | 76 ++ .../lib/types/props/private/setter_factory.rb | 197 +++ .../lib/types/props/serializable.rb | 374 +++++ .../lib/types/props/type_validation.rb | 111 ++ .../lib/types/props/utils.rb | 59 + .../lib/types/props/weak_constructor.rb | 67 + .../sorbet-runtime-0.5.10132/lib/types/sig.rb | 30 + .../lib/types/struct.rb | 18 + .../lib/types/types/attached_class.rb | 37 + .../lib/types/types/base.rb | 172 +++ .../lib/types/types/class_of.rb | 40 + .../lib/types/types/enum.rb | 40 + .../lib/types/types/fixed_array.rb | 86 ++ .../lib/types/types/fixed_hash.rb | 74 + .../lib/types/types/intersection.rb | 42 + .../lib/types/types/noreturn.rb | 29 + .../lib/types/types/proc.rb | 51 + .../lib/types/types/self_type.rb | 35 + .../lib/types/types/simple.rb | 94 ++ .../lib/types/types/t_enum.rb | 38 + .../lib/types/types/type_member.rb | 7 + .../lib/types/types/type_parameter.rb | 23 + .../lib/types/types/type_template.rb | 7 + .../lib/types/types/type_variable.rb | 34 + .../lib/types/types/typed_array.rb | 39 + .../lib/types/types/typed_enumerable.rb | 176 +++ .../lib/types/types/typed_enumerator.rb | 41 + .../lib/types/types/typed_enumerator_lazy.rb | 41 + .../lib/types/types/typed_hash.rb | 48 + .../lib/types/types/typed_range.rb | 31 + .../lib/types/types/typed_set.rb | 53 + .../lib/types/types/union.rb | 91 ++ .../lib/types/types/untyped.rb | 29 + .../lib/types/utils.rb | 209 +++ 84 files changed, 11281 insertions(+) create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb new file mode 100644 index 0000000000..c2ad5678d0 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true +# typed: true + +# This file is hand-crafted to encode the dependencies. They load the whole type +# system since there is such a high chance of it being used, using an autoloader +# wouldn't buy us any startup time saving. + +# Namespaces without any implementation +module T; end +module T::Helpers; end +module T::Private; end +module T::Private::Abstract; end +module T::Private::Types; end + +# Each section is a group that I believe need a fixed ordering. There is also +# an ordering between groups. + +# These are pre-reqs for almost everything in here. +require_relative 'types/configuration' +require_relative 'types/_types' +require_relative 'types/private/decl_state' +require_relative 'types/private/class_utils' +require_relative 'types/private/runtime_levels' +require_relative 'types/private/methods/_methods' +require_relative 'types/sig' +require_relative 'types/helpers' +require_relative 'types/private/final' +require_relative 'types/private/sealed' + +# The types themselves. First base classes +require_relative 'types/types/base' +require_relative 'types/types/typed_enumerable' +# Everything else +require_relative 'types/types/class_of' +require_relative 'types/types/enum' +require_relative 'types/types/fixed_array' +require_relative 'types/types/fixed_hash' +require_relative 'types/types/intersection' +require_relative 'types/types/noreturn' +require_relative 'types/types/proc' +require_relative 'types/types/attached_class' +require_relative 'types/types/self_type' +require_relative 'types/types/simple' +require_relative 'types/types/t_enum' +require_relative 'types/types/type_parameter' +require_relative 'types/types/typed_array' +require_relative 'types/types/typed_enumerator' +require_relative 'types/types/typed_enumerator_lazy' +require_relative 'types/types/typed_hash' +require_relative 'types/types/typed_range' +require_relative 'types/types/typed_set' +require_relative 'types/types/union' +require_relative 'types/types/untyped' +require_relative 'types/private/types/not_typed' +require_relative 'types/private/types/void' +require_relative 'types/private/types/string_holder' +require_relative 'types/private/types/type_alias' + +require_relative 'types/types/type_variable' +require_relative 'types/types/type_member' +require_relative 'types/types/type_template' + +# Call validation +require_relative 'types/private/methods/modes' +require_relative 'types/private/methods/call_validation' + +# Signature validation +require_relative 'types/private/methods/signature_validation' +require_relative 'types/abstract_utils' +require_relative 'types/private/abstract/validate' + +# Catch all. Sort of built by `cd extn; find types -type f | grep -v test | sort` +require_relative 'types/generic' +require_relative 'types/interface_wrapper' +require_relative 'types/private/abstract/declare' +require_relative 'types/private/abstract/hooks' +require_relative 'types/private/casts' +require_relative 'types/private/methods/decl_builder' +require_relative 'types/private/methods/signature' +require_relative 'types/private/retry' +require_relative 'types/utils' +require_relative 'types/boolean' + +# Props dependencies +require_relative 'types/private/abstract/data' +require_relative 'types/private/mixins/mixins' +require_relative 'types/props/_props' +require_relative 'types/props/custom_type' +require_relative 'types/props/decorator' +require_relative 'types/props/errors' +require_relative 'types/props/plugin' +require_relative 'types/props/utils' +require_relative 'types/enum' +# Props that run sigs statically so have to be after all the others :( +require_relative 'types/props/private/setter_factory' +require_relative 'types/props/private/apply_default' +require_relative 'types/props/has_lazily_specialized_methods' +require_relative 'types/props/optional' +require_relative 'types/props/weak_constructor' +require_relative 'types/props/constructor' +require_relative 'types/props/pretty_printable' +require_relative 'types/props/private/serde_transform' +require_relative 'types/props/private/deserializer_generator' +require_relative 'types/props/private/serializer_generator' +require_relative 'types/props/serializable' +require_relative 'types/props/type_validation' +require_relative 'types/props/private/parser' +require_relative 'types/props/generated_code_validation' + +require_relative 'types/struct' +require_relative 'types/non_forcing_constants' + +require_relative 'types/compatibility_patches' + +# Sorbet Compiler support module +require_relative 'types/private/compiler' diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb new file mode 100644 index 0000000000..20a0e641e0 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb @@ -0,0 +1,316 @@ +# frozen_string_literal: true +# typed: true +# This is where we define the shortcuts, so we can't use them here + +# _____ +# |_ _| _ _ __ ___ ___ +# | || | | | '_ \ / _ \/ __| +# | || |_| | |_) | __/\__ \ +# |_| \__, | .__/ \___||___/ +# |___/|_| +# +# Docs at https://sorbet.org/docs/sigs +# +# Types that you can pass to `sig`: +# +# - a Ruby class +# +# - [, , ...] -- to specify a "tuple"; a fixed-size array with known types for each member +# +# - {key: , key2: , ...} -- to speicfy a "shape"; a fixed-size hash +# with known keys and type values +# +# - Any of the `T.foo` methods below + +module T + # T.any(, , ...) -- matches any of the types listed + 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? + T::Types::Union::Private::Pool.union_of_types(type_a, type_b, types) + end + + # Shorthand for T.any(type, NilClass) + def self.nilable(type) + T::Types::Union::Private::Pool.union_of_types(T::Utils.coerce(type), T::Utils::Nilable::NIL_TYPE) + end + + # Matches any object. In the static checker, T.untyped allows any + # method calls or operations. + def self.untyped + T::Types::Untyped::Private::INSTANCE + end + + # Indicates a function never returns (e.g. "Kernel#raise") + def self.noreturn + T::Types::NoReturn::Private::INSTANCE + end + + # T.all(, , ...) -- matches an object that has all of the types listed + def self.all(type_a, type_b, *types) + T::Types::Intersection.new([type_a, type_b] + types) + end + + # Matches any of the listed values + # @deprecated Use T::Enum instead. + def self.deprecated_enum(values) + T::Types::Enum.new(values) + end + + # Creates a proc type + def self.proc + T::Private::Methods.start_proc + end + + # Matches `self`: + def self.self_type + T::Types::SelfType::Private::INSTANCE + end + + # Matches the instance type in a singleton-class context + def self.attached_class + T::Types::AttachedClassType::Private::INSTANCE + end + + # Matches any class that subclasses or includes the provided class + # or module + def self.class_of(klass) + T::Types::ClassOf.new(klass) + end + + ## END OF THE METHODS TO PASS TO `sig`. + + # Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a + # wrapper that contains a proc that is evaluated to get the underlying type. This syntax however + # is needed for support by the static checker. + # + # @example + # NilableString = T.type_alias {T.nilable(String)} + # + # sig {params(arg: NilableString, default: String).returns(String)} + # def or_else(arg, default) + # arg || default + # end + # + # The name of the type alias is not preserved; Error messages will + # be printed with reference to the underlying type. + # + # TODO Remove `type` parameter. This was left in to make life easier while migrating. + def self.type_alias(type=nil, &blk) + if blk + T::Private::Types::TypeAlias.new(blk) + else + T::Utils.coerce(type) + end + end + + # References a type parameter which was previously defined with + # `type_parameters`. + # + # This is used for generic methods. + # + # @example + # sig + # .type_parameters(:U) + # .params( + # blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U)), + # ) + # .returns(T::Array[T.type_parameter(:U)]) + # def map(&blk); end + def self.type_parameter(name) + T::Types::TypeParameter.new(name) + end + + # Tells the typechecker that `value` is of type `type`. Use this to get additional checking after + # an expression that the typechecker is unable to analyze. If `checked` is true, raises an + # exception at runtime if the value doesn't match the type. + # + # Compared to `T.let`, `T.cast` is _trusted_ by static system. + def self.cast(value, type, checked: true) + return value unless checked + + Private::Casts.cast(value, type, cast_method: "T.cast") + end + + # Tells the typechecker to declare a variable of type `type`. Use + # like: + # + # seconds = T.let(0.0, Float) + # + # Compared to `T.cast`, `T.let` is _checked_ by static system. + # + # If `checked` is true, raises an exception at runtime if the value + # doesn't match the type. + def self.let(value, type, checked: true) + return value unless checked + + Private::Casts.cast(value, type, cast_method: "T.let") + end + + # Tells the type checker to treat `self` in the current block as `type`. + # Useful for blocks that are captured and executed later with instance_exec. + # Use like: + # + # seconds = lambda do + # T.bind(self, NewBinding) + # ... + # end + # + # `T.bind` behaves like `T.cast` in that it is assumed to be true statically. + # + # If `checked` is true, raises an exception at runtime if the value + # doesn't match the type (this is the default). + def self.bind(value, type, checked: true) + return value unless checked + + Private::Casts.cast(value, type, cast_method: "T.bind") + end + + # Tells the typechecker to ensure that `value` is of type `type` (if not, the typechecker will + # fail). Use this for debugging typechecking errors, or to ensure that type information is + # statically known and being checked appropriately. If `checked` is true, raises an exception at + # runtime if the value doesn't match the type. + def self.assert_type!(value, type, checked: true) + return value unless checked + + Private::Casts.cast(value, type, cast_method: "T.assert_type!") + end + + # For the static type checker, strips all type information from a value + # and returns the same value, but statically-typed as `T.untyped`. + # Can be used to tell the static checker to "trust you" by discarding type information + # you know to be incorrect. Use with care! + # (This has no effect at runtime.) + # + # We can't actually write this sig because we ourselves are inside + # the `T::` module and doing this would create a bootstrapping + # cycle. However, we also don't actually need to do so; An untyped + # identity method works just as well here. + # + # `sig {params(value: T.untyped).returns(T.untyped)}` + def self.unsafe(value) + value + end + + # A convenience method to `raise` when the argument is `nil` and return it + # otherwise. + # + # Intended to be used as: + # + # needs_foo(T.must(maybe_gives_foo)) + # + # Equivalent to: + # + # foo = maybe_gives_foo + # raise "nil" if foo.nil? + # needs_foo(foo) + # + # Intended to be used to promise sorbet that a given nilable value happens + # to contain a non-nil value at this point. + # + # `sig {params(arg: T.nilable(A)).returns(A)}` + def self.must(arg) + return arg if arg + return arg if arg == false + + begin + raise TypeError.new("Passed `nil` into T.must") + rescue TypeError => e # raise into rescue to ensure e.backtrace is populated + T::Configuration.inline_type_error_handler(e, {kind: 'T.must', value: arg, type: nil}) + end + end + + # A way to ask Sorbet to show what type it thinks an expression has. + # This can be useful for debugging and checking assumptions. + # In the runtime, merely returns the value passed in. + def self.reveal_type(value) + value + end + + # A way to ask Sorbet to prove that a certain branch of control flow never + # happens. Commonly used to assert that a case or if statement exhausts all + # possible cases. + def self.absurd(value) + msg = "Control flow reached T.absurd." + + case value + when Kernel + msg += " Got value: #{value}" + end + + begin + raise TypeError.new(msg) + rescue TypeError => e # raise into rescue to ensure e.backtrace is populated + T::Configuration.inline_type_error_handler(e, {kind: 'T.absurd', value: value, type: nil}) + end + end + + ### Generic classes ### + + module Array + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedArray::Untyped.new + else + T::Types::TypedArray.new(type) + end + end + end + + module Hash + def self.[](keys, values) + if keys.is_a?(T::Types::Untyped) && values.is_a?(T::Types::Untyped) + T::Types::TypedHash::Untyped.new + else + T::Types::TypedHash.new(keys: keys, values: values) + end + end + end + + module Enumerable + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedEnumerable::Untyped.new + else + T::Types::TypedEnumerable.new(type) + end + end + end + + module Enumerator + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedEnumerator::Untyped.new + else + T::Types::TypedEnumerator.new(type) + end + end + + module Lazy + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedEnumeratorLazy::Untyped.new + else + T::Types::TypedEnumeratorLazy.new(type) + end + end + end + end + + module Range + def self.[](type) + T::Types::TypedRange.new(type) + end + end + + module Set + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedSet::Untyped.new + else + T::Types::TypedSet.new(type) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb new file mode 100644 index 0000000000..721bd4e0a7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true +# typed: true + +module T::AbstractUtils + Methods = T::Private::Methods + + # Returns whether a module is declared as abstract. After the module is finished being declared, + # this is equivalent to whether it has any abstract methods that haven't been implemented + # (because we validate that and raise an error otherwise). + # + # Note that checking `mod.is_a?(Abstract::Hooks)` is not a safe substitute for this method; when + # a class extends `Abstract::Hooks`, all of its subclasses, including the eventual concrete + # ones, will still have `Abstract::Hooks` as an ancestor. + def self.abstract_module?(mod) + !T::Private::Abstract::Data.get(mod, :abstract_type).nil? + end + + def self.abstract_method?(method) + signature = Methods.signature_for_method(method) + signature&.mode == Methods::Modes.abstract + end + + # Given a module, returns the set of methods declared as abstract (in itself or ancestors) + # that have not been implemented. + def self.abstract_methods_for(mod) + declared_methods = declared_abstract_methods_for(mod) + declared_methods.select do |declared_method| + actual_method = mod.instance_method(declared_method.name) + # Note that in the case where an abstract method is overridden by another abstract method, + # this method will return them both. This is intentional to ensure we validate the final + # implementation against all declarations of an abstract method (they might not all have the + # same signature). + abstract_method?(actual_method) + end + end + + # Given a module, returns the set of methods declared as abstract (in itself or ancestors) + # regardless of whether they have been implemented. + def self.declared_abstract_methods_for(mod) + methods = [] + mod.ancestors.each do |ancestor| + ancestor_methods = ancestor.private_instance_methods(false) + ancestor.instance_methods(false) + ancestor_methods.each do |method_name| + method = ancestor.instance_method(method_name) + methods << method if abstract_method?(method) + end + end + methods + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb new file mode 100644 index 0000000000..8763d8707d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb @@ -0,0 +1,8 @@ +# typed: strict +# frozen_string_literal: true + +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)} +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb new file mode 100644 index 0000000000..070b182aae --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true +# typed: ignore + +# Work around an interaction bug with sorbet-runtime and rspec-mocks, +# which occurs when using message expectations (*_any_instance_of, +# expect, allow) and and_call_original. +# +# When a sig is defined, sorbet-runtime will replace the sigged method +# with a wrapper that, upon first invocation, re-wraps the method with a faster +# implementation. +# +# When expect_any_instance_of is used, rspec stores a reference to the first wrapper, +# to be restored later. +# +# The first wrapper is invoked as part of the test and sorbet-runtime replaces +# the method definition with the second wrapper. +# +# But when mocks are cleaned up, rspec restores back to the first wrapper. +# Upon subsequent invocations, the first wrapper is called, and sorbet-runtime +# throws a runtime error, since this is an unexpected state. +# +# We work around this by forcing re-wrapping before rspec stores a reference +# to the method. +if defined? ::RSpec::Mocks + module T + module CompatibilityPatches + module RSpecCompatibility + module RecorderExtensions + def observe!(method_name) + method = @klass.instance_method(method_name.to_sym) + T::Private::Methods.maybe_run_sig_block_for_method(method) + super(method_name) + end + end + ::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions) if defined?(::RSpec::Mocks::AnyInstance::Recorder) + + module MethodDoubleExtensions + def initialize(object, method_name, proxy) + if ::Kernel.instance_method(:respond_to?).bind(object).call(method_name, true) + method = ::RSpec::Support.method_handle_for(object, method_name) + T::Private::Methods.maybe_run_sig_block_for_method(method) + end + super(object, method_name, proxy) + end + end + ::RSpec::Mocks::MethodDouble.prepend(MethodDoubleExtensions) if defined?(::RSpec::Mocks::MethodDouble) + end + end + end +end + +# Work around for sorbet-runtime wrapped methods. +# +# When a sig is defined, sorbet-runtime will replace the sigged method +# with a wrapper. Those wrapper methods look like `foo(*args, &blk)` +# so that wrappers can handle and pass on all the arguments supplied. +# +# However, that creates a problem with runtime reflection on the methods, +# since when a sigged method is introspected, it will always return its +# `arity` as `-1`, its `parameters` as `[[:rest, :args], [:block, :blk]]`, +# and its `source_location` as `[, ]`. +# +# This might be a problem for some applications that rely on getting the +# correct information from these methods. +# +# This compatibility module, when prepended to the `Method` class, would fix +# the return values of `arity`, `parameters` and `source_location`. +# +# @example +# require 'sorbet-runtime' +# ::Method.prepend(T::CompatibilityPatches::MethodExtensions) +module T + module CompatibilityPatches + module MethodExtensions + def arity + arity = super + return arity if arity != -1 || self.is_a?(Proc) + sig = T::Private::Methods.signature_for_method(self) + sig ? sig.method.arity : arity + end + + def source_location + sig = T::Private::Methods.signature_for_method(self) + sig ? sig.method.source_location : super + end + + def parameters + sig = T::Private::Methods.signature_for_method(self) + sig ? sig.method.parameters : super + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb new file mode 100644 index 0000000000..c012b6e8b6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb @@ -0,0 +1,591 @@ +# typed: true +# frozen_string_literal: true + +module T::Configuration + # Cache this comparisonn to avoid two allocations all over the place. + AT_LEAST_RUBY_2_7 = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7') + + # Announces to Sorbet that we are currently in a test environment, so it + # should treat any sigs which are marked `.checked(:tests)` as if they were + # just a normal sig. + # + # If this method is not called, sigs marked `.checked(:tests)` will not be + # checked. In fact, such methods won't even be wrapped--the runtime will put + # back the original method. + # + # Note: Due to the way sigs are evaluated and methods are wrapped, this + # method MUST be called before any code calls `sig`. This method raises if + # it has been called too late. + def self.enable_checking_for_sigs_marked_checked_tests + T::Private::RuntimeLevels.enable_checking_in_tests + end + + # Announce to Sorbet that we would like the final checks to be enabled when + # including and extending modules. Iff this is not called, then the following + # example will not raise an error. + # + # ```ruby + # module M + # extend T::Sig + # sig(:final) {void} + # def foo; end + # end + # class C + # include M + # def foo; end + # end + # ``` + def self.enable_final_checks_on_hooks + T::Private::Methods.set_final_checks_on_hooks(true) + end + + # Undo the effects of a previous call to + # `enable_final_checks_on_hooks`. + def self.reset_final_checks_on_hooks + T::Private::Methods.set_final_checks_on_hooks(false) + end + + @include_value_in_type_errors = true + # Whether to include values in TypeError messages. + # + # Including values is useful for debugging, but can potentially leak + # sensitive information to logs. + # + # @return [T::Boolean] + def self.include_value_in_type_errors? + @include_value_in_type_errors + end + + # Configure if type errors excludes the value of the problematic type. + # + # The default is to include values in type errors: + # TypeError: Expected type Integer, got String with value "foo" + # + # When values are excluded from type errors: + # TypeError: Expected type Integer, got String + def self.exclude_value_in_type_errors + @include_value_in_type_errors = false + end + + # Opposite of exclude_value_in_type_errors. + # (Including values in type errors is the default) + def self.include_value_in_type_errors + @include_value_in_type_errors = true + end + + # Whether VM-defined prop serialization/deserialization routines can be enabled. + # + # @return [T::Boolean] + def self.can_enable_vm_prop_serde? + T::Props::Private::DeserializerGenerator.respond_to?(:generate2) + end + + @use_vm_prop_serde = false + # Whether to use VM-defined prop serialization/deserialization routines. + # + # The default is to use runtime codegen inside sorbet-runtime itself. + # + # @return [T::Boolean] + def self.use_vm_prop_serde? + @use_vm_prop_serde || false + end + + # Enable using VM-defined prop serialization/deserialization routines. + # + # This method is likely to break things outside of Stripe's systems. + def self.enable_vm_prop_serde + if !can_enable_vm_prop_serde? + hard_assert_handler('Ruby VM is not setup to use VM-defined prop serde') + end + @use_vm_prop_serde = true + end + + # Disable using VM-defined prop serialization/deserialization routines. + def self.disable_vm_prop_serde + @use_vm_prop_serde = false + end + + # Configure the default checked level for a sig with no explicit `.checked` + # builder. When unset, the default checked level is `:always`. + # + # Note: setting this option is potentially dangerous! Sorbet can't check all + # code statically. The runtime checks complement the checks that Sorbet does + # statically, so that methods don't have to guard themselves from being + # called incorrectly by untyped code. + # + # @param [:never, :compiled, :tests, :always] default_checked_level + def self.default_checked_level=(default_checked_level) + T::Private::RuntimeLevels.default_checked_level = default_checked_level + end + + @inline_type_error_handler = nil + # Set a handler to handle `TypeError`s raised by any in-line type assertions, + # including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`. + # + # By default, any `TypeError`s detected by this gem will be raised. Setting + # inline_type_error_handler to an object that implements :call (e.g. proc or + # lambda) allows users to customize the behavior when a `TypeError` is + # raised on any inline type assertion. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass + # nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [TypeError] error TypeError that was raised + # @param [Hash] opts A hash containing contextual information on the error: + # @option opts [String] :kind One of: + # ['T.cast', 'T.let', 'T.bind', 'T.assert_type!', 'T.must', 'T.absurd'] + # @option opts [Object, nil] :type Expected param/return value type + # @option opts [Object] :value Actual param/return value + # + # @example + # T::Configuration.inline_type_error_handler = lambda do |error, opts| + # puts error.message + # end + def self.inline_type_error_handler=(value) + validate_lambda_given!(value) + @inline_type_error_handler = value + end + + private_class_method def self.inline_type_error_handler_default(error, opts) + raise error + end + + def self.inline_type_error_handler(error, opts={}) + if @inline_type_error_handler + # Backwards compatibility before `inline_type_error_handler` took a second arg + if @inline_type_error_handler.arity == 1 + @inline_type_error_handler.call(error) + else + @inline_type_error_handler.call(error, opts) + end + else + inline_type_error_handler_default(error, opts) + end + nil + end + + @sig_builder_error_handler = nil + # Set a handler to handle errors that occur when the builder methods in the + # body of a sig are executed. The sig builder methods are inside a proc so + # that they can be lazily evaluated the first time the method being sig'd is + # called. + # + # By default, improper use of the builder methods within the body of a sig + # cause an ArgumentError to be raised. Setting sig_builder_error_handler to an + # object that implements :call (e.g. proc or lambda) allows users to + # customize the behavior when a sig can't be built for some reason. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass + # nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [StandardError] error The error that was raised + # @param [Thread::Backtrace::Location] location Location of the error + # + # @example + # T::Configuration.sig_builder_error_handler = lambda do |error, location| + # puts error.message + # end + def self.sig_builder_error_handler=(value) + validate_lambda_given!(value) + @sig_builder_error_handler = value + end + + private_class_method def self.sig_builder_error_handler_default(error, location) + raise ArgumentError.new("#{location.path}:#{location.lineno}: Error interpreting `sig`:\n #{error.message}\n\n") + end + + def self.sig_builder_error_handler(error, location) + if @sig_builder_error_handler + @sig_builder_error_handler.call(error, location) + else + sig_builder_error_handler_default(error, location) + end + nil + end + + @sig_validation_error_handler = nil + # Set a handler to handle sig validation errors. + # + # Sig validation errors include things like abstract checks, override checks, + # and type compatibility of arguments. They happen after a sig has been + # successfully built, but the built sig is incompatible with other sigs in + # some way. + # + # By default, sig validation errors cause an exception to be raised. + # Setting sig_validation_error_handler to an object that implements :call + # (e.g. proc or lambda) allows users to customize the behavior when a method + # signature's build fails. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass + # nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [StandardError] error The error that was raised + # @param [Hash] opts A hash containing contextual information on the error: + # @option opts [Method, UnboundMethod] :method Method on which the signature build failed + # @option opts [T::Private::Methods::Declaration] :declaration Method + # signature declaration struct + # @option opts [T::Private::Methods::Signature, nil] :signature Signature + # that failed (nil if sig build failed before Signature initialization) + # @option opts [T::Private::Methods::Signature, nil] :super_signature Super + # method's signature (nil if method is not an override or super method + # does not have a method signature) + # + # @example + # T::Configuration.sig_validation_error_handler = lambda do |error, opts| + # puts error.message + # end + def self.sig_validation_error_handler=(value) + validate_lambda_given!(value) + @sig_validation_error_handler = value + end + + private_class_method def self.sig_validation_error_handler_default(error, opts) + raise error + end + + def self.sig_validation_error_handler(error, opts={}) + if @sig_validation_error_handler + @sig_validation_error_handler.call(error, opts) + else + sig_validation_error_handler_default(error, opts) + end + nil + end + + @call_validation_error_handler = nil + # Set a handler for type errors that result from calling a method. + # + # By default, errors from calling a method cause an exception to be raised. + # Setting call_validation_error_handler to an object that implements :call + # (e.g. proc or lambda) allows users to customize the behavior when a method + # is called with invalid parameters, or returns an invalid value. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error + # report (pass nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [T::Private::Methods::Signature] signature Signature that failed + # @param [Hash] opts A hash containing contextual information on the error: + # @option opts [String] :message Error message + # @option opts [String] :kind One of: + # ['Parameter', 'Block parameter', 'Return value'] + # @option opts [Symbol] :name Param or block param name (nil for return + # value) + # @option opts [Object] :type Expected param/return value type + # @option opts [Object] :value Actual param/return value + # @option opts [Thread::Backtrace::Location] :location Location of the + # caller + # + # @example + # T::Configuration.call_validation_error_handler = lambda do |signature, opts| + # puts opts[:message] + # end + def self.call_validation_error_handler=(value) + validate_lambda_given!(value) + @call_validation_error_handler = value + end + + private_class_method def self.call_validation_error_handler_default(signature, opts) + raise TypeError.new(opts[:pretty_message]) + end + + def self.call_validation_error_handler(signature, opts={}) + if @call_validation_error_handler + @call_validation_error_handler.call(signature, opts) + else + call_validation_error_handler_default(signature, opts) + end + nil + end + + @log_info_handler = nil + # Set a handler for logging + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error + # report (pass nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [String] str Message to be logged + # @param [Hash] extra A hash containing additional parameters to be passed along to the logger. + # + # @example + # T::Configuration.log_info_handler = lambda do |str, extra| + # puts "#{str}, context: #{extra}" + # end + def self.log_info_handler=(value) + validate_lambda_given!(value) + @log_info_handler = value + end + + private_class_method def self.log_info_handler_default(str, extra) + puts "#{str}, extra: #{extra}" + end + + def self.log_info_handler(str, extra) + if @log_info_handler + @log_info_handler.call(str, extra) + else + log_info_handler_default(str, extra) + end + end + + @soft_assert_handler = nil + # Set a handler for soft assertions + # + # These generally shouldn't stop execution of the program, but rather inform + # some party of the assertion to action on later. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error + # report (pass nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [String] str Assertion message + # @param [Hash] extra A hash containing additional parameters to be passed along to the handler. + # + # @example + # T::Configuration.soft_assert_handler = lambda do |str, extra| + # puts "#{str}, context: #{extra}" + # end + def self.soft_assert_handler=(value) + validate_lambda_given!(value) + @soft_assert_handler = value + end + + private_class_method def self.soft_assert_handler_default(str, extra) + puts "#{str}, extra: #{extra}" + end + + def self.soft_assert_handler(str, extra) + if @soft_assert_handler + @soft_assert_handler.call(str, extra) + else + soft_assert_handler_default(str, extra) + end + end + + @hard_assert_handler = nil + # Set a handler for hard assertions + # + # These generally should stop execution of the program, and optionally inform + # some party of the assertion. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error + # report (pass nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [String] str Assertion message + # @param [Hash] extra A hash containing additional parameters to be passed along to the handler. + # + # @example + # T::Configuration.hard_assert_handler = lambda do |str, extra| + # raise "#{str}, context: #{extra}" + # end + def self.hard_assert_handler=(value) + validate_lambda_given!(value) + @hard_assert_handler = value + end + + private_class_method def self.hard_assert_handler_default(str, _) + raise str + end + + def self.hard_assert_handler(str, extra={}) + if @hard_assert_handler + @hard_assert_handler.call(str, extra) + else + hard_assert_handler_default(str, extra) + end + end + + @scalar_types = nil + # Set a list of class strings that are to be considered scalar. + # (pass nil to reset to default behavior) + # + # @param [String] values Class name. + # + # @example + # T::Configuration.scalar_types = ["NilClass", "TrueClass", "FalseClass", ...] + def self.scalar_types=(values) + if values.nil? + @scalar_types = values + else + 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 + end + end + + @default_scalar_types = { + "NilClass" => true, + "TrueClass" => true, + "FalseClass" => true, + "Integer" => true, + "Float" => true, + "String" => true, + "Symbol" => true, + "Time" => true, + "T::Enum" => true, + }.freeze + + def self.scalar_types + @scalar_types || @default_scalar_types + end + + # Guard against overrides of `name` or `to_s` + MODULE_NAME = Module.instance_method(:name) + private_constant :MODULE_NAME + + @default_module_name_mangler = if T::Configuration::AT_LEAST_RUBY_2_7 + ->(type) {MODULE_NAME.bind_call(type)} + else + ->(type) {MODULE_NAME.bind(type).call} + end + + @module_name_mangler = nil + + def self.module_name_mangler + @module_name_mangler || @default_module_name_mangler + end + + # Set to override the default behavior for converting types + # to names in generated code. Used by the runtime implementation + # associated with `--stripe-packages` mode. + # + # @param [Lambda, Proc, nil] handler Proc that converts a type (Class/Module) + # to a String (pass nil to reset to default behavior) + def self.module_name_mangler=(handler) + @module_name_mangler = handler + end + + @sensitivity_and_pii_handler = nil + # Set to a PII handler function. This will be called with the `sensitivity:` + # annotations on things that use `T::Props` and can modify them ahead-of-time. + # + # @param [Lambda, Proc, nil] handler Proc that takes a hash mapping symbols to the + # prop values. Pass nil to avoid changing `sensitivity:` annotations. + def self.normalize_sensitivity_and_pii_handler=(handler) + @sensitivity_and_pii_handler = handler + end + + def self.normalize_sensitivity_and_pii_handler + @sensitivity_and_pii_handler + end + + @redaction_handler = nil + # Set to a redaction handling function. This will be called when the + # `_redacted` version of a prop reader is used. By default this is set to + # `nil` and will raise an exception when the redacted version of a prop is + # accessed. + # + # @param [Lambda, Proc, nil] handler Proc that converts a value into its + # redacted version according to the spec passed as the second argument. + def self.redaction_handler=(handler) + @redaction_handler = handler + end + + def self.redaction_handler + @redaction_handler + end + + @class_owner_finder = nil + # Set to a function which can get the 'owner' of a class. This is + # used in reporting deserialization errors + # + # @param [Lambda, Proc, nil] handler Proc that takes a class and + # produces its owner, or `nil` if it does not have one. + def self.class_owner_finder=(handler) + @class_owner_finder = handler + end + + def self.class_owner_finder + @class_owner_finder + end + + # Temporarily disable ruby warnings while executing the given block. This is + # useful when doing something that would normally cause a warning to be + # emitted in Ruby verbose mode ($VERBOSE = true). + # + # @yield + # + def self.without_ruby_warnings + if $VERBOSE + begin + original_verbose = $VERBOSE + $VERBOSE = false + yield + ensure + $VERBOSE = original_verbose + end + else + yield + end + end + + @legacy_t_enum_migration_mode = false + def self.enable_legacy_t_enum_migration_mode + @legacy_t_enum_migration_mode = true + end + def self.disable_legacy_t_enum_migration_mode + @legacy_t_enum_migration_mode = false + end + def self.legacy_t_enum_migration_mode? + @legacy_t_enum_migration_mode || false + end + + @prop_freeze_handler = ->(instance, prop_name) {} + + def self.prop_freeze_handler=(handler) + @prop_freeze_handler = handler + end + + def self.prop_freeze_handler + @prop_freeze_handler + end + + @sealed_violation_whitelist = nil + # @param [Array] sealed_violation_whitelist An array of Regexp to validate + # whether inheriting /including a sealed module outside the defining module + # should be allowed. Useful to whitelist benign violations, like shim files + # generated for an autoloader. + def self.sealed_violation_whitelist=(sealed_violation_whitelist) + if !@sealed_violation_whitelist.nil? + raise ArgumentError.new("Cannot overwrite sealed_violation_whitelist after setting it") + end + + case sealed_violation_whitelist + when Array + sealed_violation_whitelist.each do |x| + case x + when Regexp then nil + else raise TypeError.new("sealed_violation_whitelist accepts an Array of Regexp") + end + end + else + raise TypeError.new("sealed_violation_whitelist= accepts an Array of Regexp") + end + + @sealed_violation_whitelist = sealed_violation_whitelist + end + def self.sealed_violation_whitelist + @sealed_violation_whitelist + end + + private_class_method def self.validate_lambda_given!(value) + if !value.nil? && !value.respond_to?(:call) + raise ArgumentError.new("Provided value must respond to :call") + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb new file mode 100644 index 0000000000..c2de09abaf --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb @@ -0,0 +1,377 @@ +# frozen_string_literal: true +# typed: strict + +# Enumerations allow for type-safe declarations of a fixed set of values. +# +# Every value is a singleton instance of the class (i.e. `Suit::SPADE.is_a?(Suit) == true`). +# +# Each value has a corresponding serialized value. By default this is the constant's name converted +# to lowercase (e.g. `Suit::Club.serialize == 'club'`); however a custom value may be passed to the +# constructor. Enum will `freeze` the serialized value. +# +# @example Declaring an Enum: +# class Suit < T::Enum +# enums do +# CLUB = new +# SPADE = new +# DIAMOND = new +# HEART = new +# end +# end +# +# @example Custom serialization value: +# class Status < T::Enum +# enums do +# READY = new('rdy') +# ... +# end +# end +# +# @example Accessing values: +# Suit::SPADE +# +# @example Converting from serialized value to enum instance: +# Suit.deserialize('club') == Suit::CLUB +# +# @example Using enums in type signatures: +# sig {params(suit: Suit).returns(Boolean)} +# def is_red?(suit); ...; end +# +# WARNING: Enum instances are singletons that are shared among all their users. Their internals +# should be kept immutable to avoid unpredictable action at a distance. +class T::Enum + extend T::Sig + extend T::Props::CustomType + + # TODO(jez) Might want to restrict this, or make subclasses provide this type + SerializedVal = T.type_alias {T.untyped} + private_constant :SerializedVal + + ### Enum class methods ### + 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." \ + " Enums are not initialized until the 'enums do' block they are defined in has finished running." + end + @values + end + + # 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]))} + def self.each_value(&blk) + if blk + values.each(&blk) + else + values.each + end + end + + # Convert from serialized value to enum instance + # + # 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)} + def self.try_deserialize(serialized_val) + if @mapping.nil? + raise "Attempting to access serialization map of #{self.class} before it has been initialized." \ + " Enums are not initialized until the 'enums do' block they are defined in has finished running." + end + @mapping[serialized_val] + end + + # Convert from serialized value to enum instance. + # + # Note: It would have been nice to make this method final before people started overriding it. + # Note: Failed CriticalMethodsNoRuntimeTypingTest + # + # @return [self] + # @raise [KeyError] if serialized value does not match any instance. + 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? + raise KeyError.new("Enum #{self} key not found: #{serialized_val.inspect}") + end + res + end + + # 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)} + def self.has_serialized?(serialized_val) + if @mapping.nil? + raise "Attempting to access serialization map of #{self.class} before it has been initialized." \ + " Enums are not initialized until the 'enums do' block they are defined in has finished running." + end + @mapping.include?(serialized_val) + end + + # Note: Failed CriticalMethodsNoRuntimeTypingTest + 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 + # serialized, we throw the error on L102. + return nil if instance.nil? + + if self == T::Enum + raise "Cannot call T::Enum.serialize directly. You must call on a specific child class." + end + if instance.class != self + raise "Cannot call #serialize on a value that is not an instance of #{self}." + end + instance.serialize + end + + # Note: Failed CriticalMethodsNoRuntimeTypingTest + 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." + end + self.from_serialized(mongo_value) + end + + ### Enum instance methods ### + + sig {returns(T.self_type)} + def dup + self + end + + sig {returns(T.self_type).checked(:tests)} + def clone + self + end + + # Note: Failed CriticalMethodsNoRuntimeTypingTest + sig {returns(SerializedVal).checked(:never)} + def serialize + assert_bound! + @serialized_val + end + + 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)} + 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)} + def to_s + inspect + end + + sig {returns(String)} + def inspect + "#<#{self.class.name}::#{@const_name || '__UNINITIALIZED__'}>" + end + + sig {params(other: BasicObject).returns(T.nilable(Integer))} + def <=>(other) + case other + when self.class + self.serialize <=> other.serialize + else + nil + end + end + + # NB: Do not call this method. This exists to allow for a safe migration path in places where enum + # values are compared directly against string values. + # + # Ruby's string has a weird quirk where `'my_string' == obj` calls obj.==('my_string') if obj + # 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 + 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? + T::Configuration.soft_assert_handler( + msg, + storytime: {class: self.class.name}, + ) + serialize.to_s + else + raise NoMethodError.new(msg) + end + end + + sig {params(other: BasicObject).returns(T::Boolean).checked(:never)} + def ==(other) + case other + when String + if T::Configuration.legacy_t_enum_migration_mode? + comparison_assertion_failed(:==, other) + self.serialize == other + else + false + end + else + super(other) + end + end + + sig {params(other: BasicObject).returns(T::Boolean).checked(:never)} + def ===(other) + case other + when String + if T::Configuration.legacy_t_enum_migration_mode? + comparison_assertion_failed(:===, other) + self.serialize == other + else + false + end + else + super(other) + end + end + + 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', + storytime: { + class: self.class.name, + self: self.inspect, + other: other, + other_class: other.class.name, + method: method, + } + ) + end + + ### Private implementation ### + + sig {params(serialized_val: SerializedVal).void} + def initialize(serialized_val=nil) + raise 'T::Enum is abstract' if self.class == T::Enum + if !self.class.started_initializing? + raise "Must instantiate all enum values of #{self.class} inside 'enums do'." + end + if self.class.fully_initialized? + raise "Cannot instantiate a new enum value of #{self.class} after it has been initialized." + end + + serialized_val = serialized_val.frozen? ? serialized_val : serialized_val.dup.freeze + @serialized_val = T.let(serialized_val, T.nilable(SerializedVal)) + @const_name = T.let(nil, T.nilable(Symbol)) + self.class._register_instance(self) + end + + 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." \ + " Enums are not initialized until the 'enums do' block they are defined in has finished running." + end + end + + 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.nil? + freeze + end + + 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 + # least amount of repetition in migrated declarations. + -const_name.to_s.downcase.freeze + end + + sig {returns(T::Boolean)} + def self.started_initializing? + unless defined?(@started_initializing) + @started_initializing = T.let(false, T.nilable(T::Boolean)) + end + T.must(@started_initializing) + end + + sig {returns(T::Boolean)} + def self.fully_initialized? + unless defined?(@fully_initialized) + @fully_initialized = T.let(false, T.nilable(T::Boolean)) + end + T.must(@fully_initialized) + end + + # Maintains the order in which values are defined + sig {params(instance: T.untyped).void} + def self._register_instance(instance) + @values ||= [] + @values << T.cast(instance, T.attached_class) + end + + # 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} + 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? + raise "Enum #{self} is still initializing" if started_initializing? + + @started_initializing = true + + @values = T.let(nil, T.nilable(T::Array[T.attached_class])) + + yield + + @mapping = T.let(nil, T.nilable(T::Hash[SerializedVal, T.attached_class])) + @mapping = {} + + # Freeze the Enum class and bind the constant names into each of the instances. + self.constants(false).each do |const_name| + instance = self.const_get(const_name, false) + if !instance.is_a?(self) + raise "Invalid constant #{self}::#{const_name} on enum. " \ + "All constants defined for an enum must be instances itself (e.g. `Foo = new`)." + end + + instance._bind_name(const_name) + serialized = instance.serialize + if @mapping.include?(serialized) + raise "Enum values must have unique serializations. Value '#{serialized}' is repeated on #{self}." + end + @mapping[serialized] = instance + end + @values.freeze + @mapping.freeze + + 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')}}" + end + + @fully_initialized = true + end + + sig {params(child_class: Module).void} + def self.inherited(child_class) + super + + raise "Inheriting from children of T::Enum is prohibited" if self != T::Enum + end + + # Marshal support + sig {params(_level: Integer).returns(String)} + def _dump(_level) + Marshal.dump(serialize) + end + + sig {params(args: String).returns(T.attached_class)} + def self._load(args) + deserialize(Marshal.load(args)) # rubocop:disable Security/MarshalLoad + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb new file mode 100644 index 0000000000..58def7aa1a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +# typed: true + +# Use as a mixin with extend (`extend T::Generic`). +module T::Generic + include T::Helpers + include Kernel + + ### Class/Module Helpers ### + + def [](*types) + self + end + + def type_member(variance=:invariant, &blk) + T::Types::TypeMember.new(variance) + end + + def type_template(variance=:invariant, &blk) + T::Types::TypeTemplate.new(variance) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb new file mode 100644 index 0000000000..7f326e7384 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +# typed: true + +# Use as a mixin with extend (`extend T::Helpers`). +# Docs at https://sorbet.org/docs/ +module T::Helpers + extend T::Sig + + Private = T::Private + + ### Class/Module Helpers ### + + def abstract! + Private::Abstract::Declare.declare_abstract(self, type: :abstract) + end + + def interface! + Private::Abstract::Declare.declare_abstract(self, type: :interface) + end + + def final! + Private::Final.declare(self) + end + + def sealed! + Private::Sealed.declare(self, Kernel.caller(1..1)&.first&.split(':')&.first) + end + + # Causes a mixin to also mix in class methods from the named module. + # + # Nearly equivalent to + # + # def self.included(other) + # other.extend(mod) + # end + # + # Except that it is statically analyzed by sorbet. + def mixes_in_class_methods(mod, *mods) + Private::Mixins.declare_mixes_in_class_methods(self, [mod].concat(mods)) + end + + # Specify an inclusion or inheritance requirement for `self`. + # + # Example: + # + # module MyHelper + # extend T::Helpers + # + # requires_ancestor { Kernel } + # end + # + # class MyClass < BasicObject # error: `MyClass` must include `Kernel` (required by `MyHelper`) + # include MyHelper + # end + # + # TODO: implement the checks in sorbet-runtime. + def requires_ancestor(&block); end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb new file mode 100644 index 0000000000..82998667f7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true +# typed: false + +# Wraps an object, exposing only the methods defined on a given class/module. The idea is that, in +# the absence of a static type checker that would prevent you from calling non-Bar methods on a +# variable of type Bar, we can use these wrappers as a way of enforcing it at runtime. +# +# Once we ship static type checking, we should get rid of this entirely. +class T::InterfaceWrapper + extend T::Sig + + module Helpers + def wrap_instance(obj) + T::InterfaceWrapper.wrap_instance(obj, self) + end + + def wrap_instances(arr) + T::InterfaceWrapper.wrap_instances(arr, self) + end + end + + private_class_method :new # use `wrap_instance` + + def self.wrap_instance(obj, interface_mod) + wrapper = wrapped_dynamic_cast(obj, interface_mod) + if wrapper.nil? + raise "#{obj.class} cannot be cast to #{interface_mod}" + end + wrapper + end + + sig do + params( + arr: Array, + interface_mod: T.untyped + ) + .returns(Array) + end + def self.wrap_instances(arr, interface_mod) + arr.map {|instance| self.wrap_instance(instance, interface_mod)} + end + + def initialize(target_obj, interface_mod) + if target_obj.is_a?(T::InterfaceWrapper) + # wrapped_dynamic_cast should guarantee this never happens. + raise "Unexpected: wrapping a wrapper. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + + if !target_obj.is_a?(interface_mod) + # wrapped_dynamic_cast should guarantee this never happens. + raise "Unexpected: `is_a?` failed. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + + if target_obj.class == interface_mod + # wrapped_dynamic_cast should guarantee this never happens. + raise "Unexpected: exact class match. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + + @target_obj = target_obj + @interface_mod = interface_mod + self_methods = self.class.self_methods + + # If perf becomes an issue, we can define these on an anonymous subclass, and keep a cache + # so we only need to do it once per unique `interface_mod` + T::Utils.methods_excluding_object(interface_mod).each do |method_name| + if self_methods.include?(method_name) + raise "interface_mod has a method that conflicts with #{self.class}: #{method_name}" + end + + define_singleton_method(method_name) do |*args, &blk| + target_obj.send(method_name, *args, &blk) + end + + if target_obj.singleton_class.public_method_defined?(method_name) + # no-op, it's already public + elsif target_obj.singleton_class.protected_method_defined?(method_name) + singleton_class.send(:protected, method_name) + elsif target_obj.singleton_class.private_method_defined?(method_name) + singleton_class.send(:private, method_name) + else + raise "This should never happen. Report this bug at https://github.com/sorbet/sorbet/issues" + end + end + end + + def kind_of?(other) + is_a?(other) + end + + def is_a?(other) + if !other.is_a?(Module) + raise TypeError.new("class or module required") + end + + # This makes is_a? return true for T::InterfaceWrapper (and its ancestors), + # as well as for @interface_mod and its ancestors. + self.class <= other || @interface_mod <= other + end + + # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't + # want anyone else (besides dynamic_cast) calling it. + def __target_obj_DO_NOT_USE # rubocop:disable Naming/MethodName + @target_obj + end + + # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't + # want anyone else (besides wrapped_dynamic_cast) calling it. + def __interface_mod_DO_NOT_USE # rubocop:disable Naming/MethodName + @interface_mod + end + + # "Cast" an object to another type. If `obj` is an InterfaceWrapper, returns the the wrapped + # object if that matches `type`. Otherwise, returns `obj` if it matches `type`. Otherwise, + # returns nil. + # + # @param obj [Object] object to cast + # @param mod [Module] type to cast `obj` to + # + # @example + # if (impl = T::InterfaceWrapper.dynamic_cast(iface, MyImplementation)) + # impl.do_things + # end + def self.dynamic_cast(obj, mod) + if obj.is_a?(T::InterfaceWrapper) + target_obj = obj.__target_obj_DO_NOT_USE + target_obj.is_a?(mod) ? target_obj : nil + elsif obj.is_a?(mod) + obj + else + nil + end + end + + # Like dynamic_cast, but puts the result in its own wrapper if necessary. + # + # @param obj [Object] object to cast + # @param mod [Module] type to cast `obj` to + def self.wrapped_dynamic_cast(obj, mod) + # Avoid unwrapping and creating an equivalent wrapper. + if obj.is_a?(T::InterfaceWrapper) && obj.__interface_mod_DO_NOT_USE == mod + return obj + end + + cast_obj = dynamic_cast(obj, mod) + if cast_obj.nil? + nil + elsif cast_obj.class == mod + # Nothing to wrap, they want the full class + cast_obj + else + new(cast_obj, mod) + end + end + + def self.self_methods + @self_methods ||= self.instance_methods(false).to_set + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb new file mode 100644 index 0000000000..96445357cb --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true +# typed: strict + +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, package: T.nilable(String)).returns(T::Boolean)} + def self.non_forcing_is_a?(val, klass, package: nil) + method_name = "T::NonForcingConstants.non_forcing_is_a?" + if klass.empty? + raise ArgumentError.new("The string given to `#{method_name}` must not be empty") + end + + # We don't treat packages differently at runtime, but the static + # type-checker still needs to have the package and constant + # separated out. This just re-assembles the string as needed + if !package.nil? + klass = "::#{package}::#{klass}" + end + + current_klass = T.let(nil, T.nilable(Module)) + current_prefix = T.let(nil, T.nilable(String)) + + parts = klass.split('::') + parts.each do |part| + if current_klass.nil? + # First iteration + if part != "" && package.nil? + # if we've supplied a package, we're probably running in + # package mode, which means absolute references are + # meaningless + raise ArgumentError.new("The string given to `#{method_name}` must be an absolute constant reference that starts with `::`") + end + + current_klass = Object + current_prefix = '' + + # if this had a :: prefix, then there's no more loading to + # do---skip to the next one + next if part == "" + end + + if current_klass.autoload?(part) + # There's an autoload registered for that constant, which means it's not + # yet loaded. `value` can't be an instance of something not yet loaded. + return false + end + + # Sorbet guarantees that the string is an absolutely resolved name. + search_inheritance_chain = false + if !current_klass.const_defined?(part, search_inheritance_chain) + return false + end + + current_klass = current_klass.const_get(part) + current_prefix = "#{current_prefix}::#{part}" + + if !Module.===(current_klass) + raise ArgumentError.new("#{current_prefix} is not a class or module") + end + end + + current_klass.===(val) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb new file mode 100644 index 0000000000..2692858ddf --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true +# typed: true + +# We need to associate data with abstract modules. We could add instance methods to them that +# access ivars, but those methods will unnecessarily pollute the module namespace, and they'd +# have access to other private state and methods that they don't actually need. We also need to +# associate data with arbitrary classes/modules that implement abstract mixins, where we don't +# control the interface at all. So, we access data via these `get` and `set` methods. +# +# Using instance_variable_get/set here is gross, but the alternative is to use a hash keyed on +# `mod`, and we can't trust that arbitrary modules can be added to those, because there are lurky +# modules that override the `hash` method with something completely broken. +module T::Private::Abstract::Data + def self.get(mod, key) + mod.instance_variable_get("@opus_abstract__#{key}") if key?(mod, key) + end + + def self.set(mod, key, value) + mod.instance_variable_set("@opus_abstract__#{key}", value) + end + + def self.key?(mod, key) + mod.instance_variable_defined?("@opus_abstract__#{key}") + end + + # Works like `setdefault` in Python. If key has already been set, return its value. If not, + # insert `key` with a value of `default` and return `default`. + def self.set_default(mod, key, default) + if self.key?(mod, key) + self.get(mod, key) + else + self.set(mod, key, default) + default + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb new file mode 100644 index 0000000000..ce8ddf9531 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Abstract::Declare + Abstract = T::Private::Abstract + AbstractUtils = T::AbstractUtils + + def self.declare_abstract(mod, type:) + if AbstractUtils.abstract_module?(mod) + raise "#{mod} is already declared as abstract" + end + if T::Private::Final.final_module?(mod) + raise "#{mod} was already declared as final and cannot be declared as abstract" + end + + Abstract::Data.set(mod, :can_have_abstract_methods, true) + Abstract::Data.set(mod.singleton_class, :can_have_abstract_methods, true) + Abstract::Data.set(mod, :abstract_type, type) + + mod.extend(Abstract::Hooks) + mod.extend(T::InterfaceWrapper::Helpers) + + if mod.is_a?(Class) + if type == :interface + # Since `interface!` is just `abstract!` with some extra validation, we could technically + # allow this, but it's unclear there are good use cases, and it might be confusing. + raise "Classes can't be interfaces. Use `abstract!` instead of `interface!`." + end + + if mod.instance_method(:initialize).owner == mod + raise "You must call `abstract!` *before* defining an initialize method" + end + + # Don't need to silence warnings via without_ruby_warnings when calling + # define_method because of the guard above + + mod.send(:define_method, :initialize) do |*args, &blk| + if self.class == mod + raise "#{mod} is declared as abstract; it cannot be instantiated" + end + super(*args, &blk) + end + + # Ruby doesn not emit "method redefined" warnings for aliased methods + # (more robust than undef_method that would create a small window in which the method doesn't exist) + mod.send(:alias_method, :initialize, :initialize) + + if mod.respond_to?(:ruby2_keywords, true) + mod.send(:ruby2_keywords, :initialize) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb new file mode 100644 index 0000000000..fae9593ae8 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Abstract::Hooks + # This will become the self.extend_object method on a module that extends Abstract::Hooks. + # It gets called when *that* module gets extended in another class/module (similar to the + # `extended` hook, but this gets calls before the ancestors of `other` get modified, which + # is important for our validation). + private def extend_object(other) + T::Private::Abstract::Data.set(self, :last_used_by, other) + super + end + + # This will become the self.append_features method on a module that extends Abstract::Hooks. + # It gets called when *that* module gets included in another class/module (similar to the + # `included` hook, but this gets calls before the ancestors of `other` get modified, which + # is important for our validation). + private def append_features(other) + T::Private::Abstract::Data.set(self, :last_used_by, other) + super + end + + # This will become the self.inherited method on a class that extends Abstract::Hooks. + # It gets called when *that* class gets inherited by another class. + private def inherited(other) + super + # `self` may not actually be abstract -- it could be a concrete class that inherited from an + # abstract class. We only need to check this in `inherited` because, for modules being included + # or extended, the concrete ones won't have these hooks at all. This is just an optimization. + return if !T::AbstractUtils.abstract_module?(self) + + T::Private::Abstract::Data.set(self, :last_used_by, other) + end + + # This will become the self.prepended method on a module that extends Abstract::Hooks. + # It will get called when *that* module gets prepended in another class/module. + private def prepended(other) + # Prepending abstract methods is weird. You'd only be able to override them via other prepended + # modules, or in subclasses. Punt until we have a use case. + Kernel.raise "Prepending abstract mixins is not currently supported." + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb new file mode 100644 index 0000000000..ba0b57775c --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Abstract::Validate + Abstract = T::Private::Abstract + AbstractUtils = T::AbstractUtils + Methods = T::Private::Methods + SignatureValidation = T::Private::Methods::SignatureValidation + + def self.validate_abstract_module(mod) + type = Abstract::Data.get(mod, :abstract_type) + validate_interface(mod) if type == :interface + end + + # Validates a class/module with an abstract class/module as an ancestor. This must be called + # after all methods on `mod` have been defined. + def self.validate_subclass(mod) + can_have_abstract_methods = !T::Private::Abstract::Data.get(mod, :can_have_abstract_methods) + unimplemented_methods = [] + + T::AbstractUtils.declared_abstract_methods_for(mod).each do |abstract_method| + implementation_method = mod.instance_method(abstract_method.name) + if AbstractUtils.abstract_method?(implementation_method) + # Note that when we end up here, implementation_method might not be the same as + # abstract_method; the latter could've been overridden by another abstract method. In either + # case, if we have a concrete definition in an ancestor, that will end up as the effective + # implementation (see CallValidation.wrap_method_if_needed), so that's what we'll validate + # against. + implementation_method = T.unsafe(nil) + mod.ancestors.each do |ancestor| + if ancestor.instance_methods.include?(abstract_method.name) + method = ancestor.instance_method(abstract_method.name) + T::Private::Methods.maybe_run_sig_block_for_method(method) + if !T::AbstractUtils.abstract_method?(method) + implementation_method = method + break + end + end + end + if !implementation_method + # There's no implementation + if can_have_abstract_methods + unimplemented_methods << describe_method(abstract_method) + end + next # Nothing to validate + end + end + + implementation_signature = Methods.signature_for_method(implementation_method) + # When a signature exists and the method is defined directly on `mod`, we skip the validation + # here, because it will have already been done when the method was defined (by + # T::Private::Methods._on_method_added). + next if implementation_signature&.owner == mod + + # We validate the remaining cases here: (a) methods defined directly on `mod` without a + # signature and (b) methods from ancestors (note that these ancestors can come before or + # after the abstract module in the inheritance chain -- the former coming from + # walking `mod.ancestors` above). + abstract_signature = Methods.signature_for_method(abstract_method) + # We allow implementation methods to be defined without a signature. + # In that case, get its untyped signature. + implementation_signature ||= Methods::Signature.new_untyped( + method: implementation_method, + mode: Methods::Modes.override + ) + SignatureValidation.validate_override_shape(implementation_signature, abstract_signature) + SignatureValidation.validate_override_types(implementation_signature, abstract_signature) + end + + method_type = mod.singleton_class? ? "class" : "instance" + if !unimplemented_methods.empty? + raise "Missing implementation for abstract #{method_type} method(s) in #{mod}:\n" \ + "#{unimplemented_methods.join("\n")}\n" \ + "If #{mod} is meant to be an abstract class/module, you can call " \ + "`abstract!` or `interface!`. Otherwise, you must implement the method(s)." + end + end + + private_class_method def self.validate_interface_all_abstract(mod, method_names) + violations = method_names.map do |method_name| + method = mod.instance_method(method_name) + if !AbstractUtils.abstract_method?(method) + describe_method(method, show_owner: false) + end + end.compact + + if !violations.empty? + raise "`#{mod}` is declared as an interface, but the following methods are not declared " \ + "with `abstract`:\n#{violations.join("\n")}" + end + end + + private_class_method def self.validate_interface(mod) + interface_methods = T::Utils.methods_excluding_object(mod) + validate_interface_all_abstract(mod, interface_methods) + validate_interface_all_public(mod, interface_methods) + end + + private_class_method def self.validate_interface_all_public(mod, method_names) + violations = method_names.map do |method_name| + if !mod.public_method_defined?(method_name) + describe_method(mod.instance_method(method_name), show_owner: false) + end + end.compact + + if !violations.empty? + raise "All methods on an interface must be public. If you intend to have non-public " \ + "methods, declare your class/module using `abstract!` instead of `interface!`. " \ + "The following methods on `#{mod}` are not public: \n#{violations.join("\n")}" + end + end + + private_class_method def self.describe_method(method, show_owner: true) + loc = if method.source_location + method.source_location.join(':') + else + "" + end + + owner = if show_owner + " declared in #{method.owner}" + else + "" + end + + " * `#{method.name}`#{owner} at #{loc}" + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb new file mode 100644 index 0000000000..f771090814 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true +# typed: false + +module T::Private + module Casts + def self.cast(value, type, cast_method:) + begin + error = T::Utils.coerce(type).error_message_for_obj(value) + return value unless error + + caller_loc = T.must(caller_locations(2..2)).first + + suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}" + + raise TypeError.new("#{cast_method}: #{error}\n#{suffix}") + rescue TypeError => e # raise into rescue to ensure e.backtrace is populated + T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type}) + value + end + end + + # there's a lot of shared logic with the above one, but factoring + # it out like this makes it easier to hopefully one day delete + # this one + def self.cast_recursive(value, type, cast_method:) + begin + error = T::Utils.coerce(type).error_message_for_obj_recursive(value) + return value unless error + + caller_loc = T.must(caller_locations(2..2)).first + + suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}" + + raise TypeError.new("#{cast_method}: #{error}\n#{suffix}") + rescue TypeError => e # raise into rescue to ensure e.backtrace is populated + T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type}) + value + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb new file mode 100644 index 0000000000..269b70cbee --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true +# typed: false + +# Cut down version of Chalk::Tools::ClassUtils with only :replace_method functionality. +# Extracted to a separate namespace so the type system can be used standalone. +module T::Private::ClassUtils + class ReplacedMethod + def initialize(mod, old_method, new_method, overwritten, visibility) + if old_method.name != new_method.name + raise "Method names must match. old=#{old_method.name} new=#{new_method.name}" + end + @mod = mod + @old_method = old_method + @new_method = new_method + @overwritten = overwritten + @name = old_method.name + @visibility = visibility + @restored = false + end + + def restore + # The check below would also catch this, but this makes the failure mode much clearer + if @restored + raise "Method '#{@name}' on '#{@mod}' was already restored" + end + + if @mod.instance_method(@name) != @new_method + raise "Trying to restore #{@mod}##{@name} but the method has changed since the call to replace_method" + end + + @restored = true + + if @overwritten + # The original method was overwritten. Overwrite again to restore it. + T::Configuration.without_ruby_warnings do + @mod.send(:define_method, @old_method.name, @old_method) + end + else + # The original method was in an ancestor. Restore it by removing the overriding method. + @mod.send(:remove_method, @old_method.name) + end + + # Restore the visibility. Note that we need to do this even when we call remove_method + # above, because the module may have set custom visibility for a method it inherited. + @mod.send(@visibility, @old_method.name) + + nil + end + + def bind(obj) + @old_method.bind(obj) + end + + def to_s + @old_method.to_s + end + end + + # `name` must be an instance method (for class methods, pass in mod.singleton_class) + private_class_method def self.visibility_method_name(mod, name) + if mod.public_method_defined?(name) + :public + elsif mod.protected_method_defined?(name) + :protected + elsif mod.private_method_defined?(name) + :private + else + raise NameError.new("undefined method `#{name}` for `#{mod}`") + end + end + + # Replaces a method, either by overwriting it (if it is defined directly on `mod`) or by + # overriding it (if it is defined by one of mod's ancestors). Returns a ReplacedMethod instance + # on which you can call `bind(...).call(...)` to call the original method, or `restore` to + # restore the original method (by overwriting or removing the override). + def self.replace_method(mod, name, &blk) + original_method = mod.instance_method(name) + original_visibility = visibility_method_name(mod, name) + original_owner = original_method.owner + + mod.ancestors.each do |ancestor| + break if ancestor == mod + if ancestor == original_owner + # If we get here, that means the method we're trying to replace exists on a *prepended* + # mixin, which means in order to supersede it, we'd need to create a method on a new + # module that we'd prepend before `ancestor`. The problem with that approach is there'd + # be no way to remove that new module after prepending it, so we'd be left with these + # empty anonymous modules in the ancestor chain after calling `restore`. + # + # That's not necessarily a deal breaker, but for now, we're keeping it as unsupported. + raise "You're trying to replace `#{name}` on `#{mod}`, but that method exists in a " \ + "prepended module (#{ancestor}), which we don't currently support." + end + end + + overwritten = original_owner == mod + T::Configuration.without_ruby_warnings do + T::Private::DeclState.current.without_on_method_added do + mod.send(:define_method, name, &blk) + if blk.arity < 0 && mod.respond_to?(:ruby2_keywords, true) + mod.send(:ruby2_keywords, name) + end + end + end + mod.send(original_visibility, name) + new_method = mod.instance_method(name) + + ReplacedMethod.new(mod, original_method, new_method, overwritten, original_visibility) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb new file mode 100644 index 0000000000..fed86b40f3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true +# typed: true + +module T::Private + module Compiler + # If this code ever runs, the caller is running interpreted (or the + # compiler didn't see the call to `running_compiled?` statically.) + # + # The Sorbet Compiler replaces calls to this method unconditionally (no + # runtime guards) to return `true` when compiling a file. + def self.running_compiled? + false + end + + # Returns `nil` because the compiler isn't running. + # + # The Sorbet Compiler replaces calls to this method unconditionally (no + # runtime guards) to return a String showing the Sorbet Compiler's version + # string. + def self.compiler_version + nil + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb new file mode 100644 index 0000000000..8eeae57e4c --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +# typed: true + +class T::Private::DeclState + def self.current + Thread.current[:opus_types__decl_state] ||= self.new + end + + def self.current=(other) + Thread.current[:opus_types__decl_state] = other + end + + attr_accessor :active_declaration + attr_accessor :skip_on_method_added + + def reset! + self.active_declaration = nil + end + + def without_on_method_added + begin + # explicit 'self' is needed here + old_value = self.skip_on_method_added + self.skip_on_method_added = true + yield + ensure + self.skip_on_method_added = old_value + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb new file mode 100644 index 0000000000..9ca747248e --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true +# typed: false + +module T::Private::Final + module NoInherit + def inherited(arg) + super(arg) + raise "#{self} was declared as final and cannot be inherited" + end + end + + module NoIncludeExtend + def included(arg) + super(arg) + raise "#{self} was declared as final and cannot be included" + end + + def extended(arg) + super(arg) + raise "#{self} was declared as final and cannot be extended" + end + end + + def self.declare(mod) + if !mod.is_a?(Module) + raise "#{mod} is not a class or module and cannot be declared as final with `final!`" + end + if final_module?(mod) + raise "#{mod} was already declared as final and cannot be re-declared as final" + end + if T::AbstractUtils.abstract_module?(mod) + raise "#{mod} was already declared as abstract and cannot be declared as final" + end + if T::Private::Sealed.sealed_module?(mod) + raise "#{mod} was already declared as sealed and cannot be declared as final" + end + mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend) + mark_as_final_module(mod) + mark_as_final_module(mod.singleton_class) + T::Private::Methods.install_hooks(mod) + end + + def self.final_module?(mod) + mod.instance_variable_defined?(:@sorbet_final_module) + end + + private_class_method def self.mark_as_final_module(mod) + mod.instance_variable_set(:@sorbet_final_module, true) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb new file mode 100644 index 0000000000..1720892a95 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb @@ -0,0 +1,581 @@ +# frozen_string_literal: true +# typed: false + +module T::Private::Methods + @installed_hooks = {} + @signatures_by_method = {} + @sig_wrappers = {} + @sigs_that_raised = {} + # stores method names that were declared final without regard for where. + # enables early rejection of names that we know can't induce final method violations. + @was_ever_final_names = {} + # maps from a module's object_id to the set of final methods declared in that module. + # we also overload entries slightly: if the value is nil, that means that the + # module has final methods somewhere along its ancestor chain, but does not itself + # have any final methods. + # + # we need the latter information to know whether we need to check along the ancestor + # chain for final method violations. we need the former information because we + # care about exactly where a final method is defined (e.g. including the same module + # 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} + # 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. + @old_hooks = nil + + ARG_NOT_PROVIDED = Object.new + PROC_TYPE = Object.new + + DeclarationBlock = Struct.new(:mod, :loc, :blk, :final, :raw) + + def self.declare_sig(mod, loc, arg, &blk) + T::Private::DeclState.current.active_declaration = _declare_sig_internal(mod, loc, arg, &blk) + + nil + end + + # See tests for how to use this. But you shouldn't be using this. + def self._declare_sig(mod, arg=nil, &blk) + _declare_sig_internal(mod, caller_locations(1, 1).first, arg, raw: true, &blk) + end + + private_class_method def self._declare_sig_internal(mod, loc, arg, raw: false, &blk) + install_hooks(mod) + + if T::Private::DeclState.current.active_declaration + T::Private::DeclState.current.reset! + raise "You called sig twice without declaring a method in between" + end + + if !arg.nil? && arg != :final + raise "Invalid argument to `sig`: #{arg}" + end + + DeclarationBlock.new(mod, loc, blk, arg == :final, raw) + end + + def self._with_declared_signature(mod, declblock, &blk) + # If declblock is provided, this code is equivalent to the check in + # _declare_sig_internal, above. + # If declblock is not provided and we have an active declaration, we are + # obviously doing something wrong. + if T::Private::DeclState.current.active_declaration + T::Private::DeclState.current.reset! + raise "You called sig twice without declaring a method in between" + end + if declblock + T::Private::DeclState.current.active_declaration = declblock + end + mod.module_exec(&blk) + end + + def self.start_proc + DeclBuilder.new(PROC_TYPE, false) + end + + def self.finalize_proc(decl) + decl.finalized = true + + if decl.mode != Modes.standard + raise "Procs cannot have override/abstract modifiers" + end + if decl.mod != PROC_TYPE + raise "You are passing a DeclBuilder as a type. Did you accidentally use `self` inside a `sig` block?" + end + if decl.returns == ARG_NOT_PROVIDED + raise "Procs must specify a return type" + end + if decl.on_failure != ARG_NOT_PROVIDED + raise "Procs cannot use .on_failure" + end + + if decl.params == ARG_NOT_PROVIDED + decl.params = {} + end + + T::Types::Proc.new(decl.params, decl.returns) + end + + # Returns the signature for a method whose definition was preceded by `sig`. + # + # @param method [UnboundMethod] + # @return [T::Private::Methods::Signature] + def self.signature_for_method(method) + signature_for_key(method_to_key(method)) + end + + private_class_method def self.signature_for_key(key) + maybe_run_sig_block_for_key(key) + + # If a subclass Sub inherits a method `foo` from Base, then + # Sub.instance_method(:foo) != Base.instance_method(:foo) even though they resolve to the + # same method. Similarly, Foo.method(:bar) != Foo.singleton_class.instance_method(:bar). + # So, we always do the look up by the method on the owner (Base in this example). + @signatures_by_method[key] + end + + # when target includes a module with instance methods source_method_names, ensure there is zero intersection between + # the final instance methods of target and source_method_names. so, for every m in source_method_names, check if there + # is already a method defined on one of target_ancestors with the same name that is final. + # + # we assume that source_method_names has already been filtered to only include method + # names that were declared final at one point. + def self._check_final_ancestors(target, target_ancestors, source_method_names, source) + source_ancestors = nil + # use reverse_each to check farther-up ancestors first, for better error messages. + target_ancestors.reverse_each do |ancestor| + final_methods = @modules_with_final.fetch(ancestor.object_id, nil) + # In this case, either ancestor didn't have any final methods anywhere in its + # ancestor chain, or ancestor did have final methods somewhere in its ancestor + # chain, but no final methods defined in ancestor itself. Either way, there + # are no final methods to check here, so we can move on to the next ancestor. + next unless final_methods + source_method_names.each do |method_name| + next unless final_methods.include?(method_name) + + # If we get here, we are defining a method that some ancestor declared as + # final. however, we permit a final method to be defined multiple + # times if it is the same final method being defined each time. + if source + if !source_ancestors + source_ancestors = source.ancestors + # filter out things without actual final methods just to make sure that + # the below checks (which should be uncommon) go as quickly as possible. + source_ancestors.select! do |a| + @modules_with_final.fetch(a.object_id, nil) + end + end + # final-ness means that there should be no more than one index for which + # the below block returns true. + defining_ancestor_idx = source_ancestors.index do |a| + @modules_with_final.fetch(a.object_id).include?(method_name) + end + next if defining_ancestor_idx && source_ancestors[defining_ancestor_idx] == ancestor + end + + definition_file, definition_line = T::Private::Methods.signature_for_method(ancestor.instance_method(method_name)).method.source_location + is_redefined = target == ancestor + caller_loc = caller_locations&.find {|l| !l.to_s.match?(%r{sorbet-runtime[^/]*/lib/})} + extra_info = "\n" + if caller_loc + extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n" + end + + error_message = "The method `#{method_name}` on #{ancestor} was declared as final and cannot be " + + (is_redefined ? "redefined" : "overridden in #{target}") + pretty_message = "#{error_message}\n" \ + "Made final here: #{definition_file}:#{definition_line}\n" \ + "#{extra_info}" + + begin + raise pretty_message + rescue => e + # sig_validation_error_handler raises by default; on the off chance that + # it doesn't raise, we need to ensure that the rest of signature building + # sees a consistent state. This sig failed to validate, so we should get + # rid of it. If we don't do this, errors of the form "You called sig + # twice without declaring a method in between" will non-deterministically + # crop up in tests. + T::Private::DeclState.current.reset! + T::Configuration.sig_validation_error_handler(e, {}) + end + end + end + end + + def self.add_module_with_final_method(mod, method_name, is_singleton_method) + m = is_singleton_method ? mod.singleton_class : mod + mid = m.object_id + methods = @modules_with_final[mid] + if methods.nil? + methods = {} + @modules_with_final[mid] = methods + end + methods[method_name] = true + nil + end + + def self.note_module_deals_with_final(mod) + # Side-effectfully initialize the value if it's not already there + @modules_with_final[mod.object_id] + @modules_with_final[mod.singleton_class.object_id] + end + + # Only public because it needs to get called below inside the replace_method blocks below. + def self._on_method_added(hook_mod, method_name, is_singleton_method: false) + if T::Private::DeclState.current.skip_on_method_added + return + end + + current_declaration = T::Private::DeclState.current.active_declaration + mod = is_singleton_method ? hook_mod.singleton_class : hook_mod + + if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final) + raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final" + end + # Don't compute mod.ancestors if we don't need to bother checking final-ness. + if @was_ever_final_names.include?(method_name) && @modules_with_final.include?(mod.object_id) + _check_final_ancestors(mod, mod.ancestors, [method_name], nil) + # We need to fetch the active declaration again, as _check_final_ancestors + # may have reset it (see the comment in that method for details). + current_declaration = T::Private::DeclState.current.active_declaration + end + + if current_declaration.nil? + return + end + T::Private::DeclState.current.reset! + + if method_name == :method_added || method_name == :singleton_method_added + raise( + "Putting a `sig` on `#{method_name}` is not supported" \ + " (sorbet-runtime uses this method internally to perform `sig` validation logic)" + ) + end + + original_method = mod.instance_method(method_name) + sig_block = lambda do + T::Private::Methods.run_sig(hook_mod, method_name, original_method, current_declaration) + end + + # Always replace the original method with this wrapper, + # which is called only on the *first* invocation. + # This wrapper is very slow, so it will subsequently re-wrap with a much faster wrapper + # (or unwrap back to the original method). + key = method_owner_and_name_to_key(mod, method_name) + unless current_declaration.raw + T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk| + method_sig = T::Private::Methods.maybe_run_sig_block_for_key(key) + method_sig ||= T::Private::Methods._handle_missing_method_signature( + self, + original_method, + __callee__, + ) + + # Should be the same logic as CallValidation.wrap_method_if_needed but we + # don't want that extra layer of indirection in the callstack + if method_sig.mode == T::Private::Methods::Modes.abstract + # We're in an interface method, keep going up the chain + if defined?(super) + super(*args, &blk) + else + raise NotImplementedError.new("The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation.") + end + # Note, this logic is duplicated (intentionally, for micro-perf) at `CallValidation.wrap_method_if_needed`, + # make sure to keep changes in sync. + elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) + CallValidation.validate_call(self, original_method, method_sig, args, blk) + elsif T::Configuration::AT_LEAST_RUBY_2_7 + original_method.bind_call(self, *args, &blk) + else + original_method.bind(self).call(*args, &blk) + end + end + end + + @sig_wrappers[key] = sig_block + if current_declaration.final + @was_ever_final_names[method_name] = true + # use hook_mod, not mod, because for example, we want class C to be marked as having final if we def C.foo as + # final. change this to mod to see some final_method tests fail. + note_module_deals_with_final(hook_mod) + add_module_with_final_method(hook_mod, method_name, is_singleton_method) + end + end + + def self._handle_missing_method_signature(receiver, original_method, callee) + method_sig = T::Private::Methods.signature_for_method(original_method) + if !method_sig + raise "`sig` not present for method `#{callee}` on #{receiver.inspect} but you're trying to run it anyways. " \ + "This should only be executed if you used `alias_method` to grab a handle to a method after `sig`ing it, but that clearly isn't what you are doing. " \ + "Maybe look to see if an exception was thrown in your `sig` lambda or somehow else your `sig` wasn't actually applied to the method." + end + + if receiver.class <= original_method.owner + receiving_class = receiver.class + elsif receiver.singleton_class <= original_method.owner + receiving_class = receiver.singleton_class + elsif receiver.is_a?(Module) && receiver <= original_method.owner + receiving_class = receiver + else + raise "#{receiver} is not related to #{original_method} - how did we get here?" + end + + # Check for a case where `alias` or `alias_method` was called for a + # method which had already had a `sig` applied. In that case, we want + # to avoid hitting this slow path again, by moving to a faster validator + # just like we did or will for the original method. + # + # If this isn't an `alias` or `alias_method` case, we're probably in the + # middle of some metaprogramming using a Method object, e.g. a pattern like + # `arr.map(&method(:foo))`. There's nothing really we can do to optimize + # that here. + receiving_method = receiving_class.instance_method(callee) + if receiving_method != original_method && receiving_method.original_name == original_method.name + aliasing_mod = receiving_method.owner + method_sig = method_sig.as_alias(callee) + unwrap_method(aliasing_mod, method_sig, original_method) + end + + method_sig + end + + # Executes the `sig` block, and converts the resulting Declaration + # to a Signature. + def self.run_sig(hook_mod, method_name, original_method, declaration_block) + current_declaration = + begin + run_builder(declaration_block) + rescue DeclBuilder::BuilderError => e + T::Configuration.sig_builder_error_handler(e, declaration_block.loc) + nil + end + + signature = + if current_declaration + build_sig(hook_mod, method_name, original_method, current_declaration, declaration_block.loc) + else + Signature.new_untyped(method: original_method) + end + + unwrap_method(signature.method.owner, signature, original_method) + signature + end + + def self.run_builder(declaration_block) + builder = DeclBuilder.new(declaration_block.mod, declaration_block.raw) + builder + .instance_exec(&declaration_block.blk) + .finalize! + .decl + end + + def self.build_sig(hook_mod, method_name, original_method, current_declaration, loc) + begin + # We allow `sig` in the current module's context (normal case) and + if hook_mod != current_declaration.mod && + # inside `class << self`, and + hook_mod.singleton_class != current_declaration.mod && + # on `self` at the top level of a file + current_declaration.mod != TOP_SELF + raise "A method (#{method_name}) is being added on a different class/module (#{hook_mod}) than the " \ + "last call to `sig` (#{current_declaration.mod}). Make sure each call " \ + "to `sig` is immediately followed by a method definition on the same " \ + "class/module." + end + + signature = Signature.new( + method: original_method, + method_name: method_name, + raw_arg_types: current_declaration.params, + raw_return_type: current_declaration.returns, + bind: current_declaration.bind, + mode: current_declaration.mode, + check_level: current_declaration.checked, + on_failure: current_declaration.on_failure, + override_allow_incompatible: current_declaration.override_allow_incompatible, + defined_raw: current_declaration.raw, + ) + + SignatureValidation.validate(signature) + signature + rescue => e + super_method = original_method&.super_method + super_signature = signature_for_method(super_method) if super_method + + T::Configuration.sig_validation_error_handler( + e, + method: original_method, + declaration: current_declaration, + signature: signature, + super_signature: super_signature + ) + + Signature.new_untyped(method: original_method) + end + end + + def self.unwrap_method(mod, signature, original_method) + maybe_wrapped_method = CallValidation.wrap_method_if_needed(mod, signature, original_method) + @signatures_by_method[method_to_key(maybe_wrapped_method)] = signature + end + + def self.has_sig_block_for_method(method) + has_sig_block_for_key(method_to_key(method)) + end + + private_class_method def self.has_sig_block_for_key(key) + @sig_wrappers.key?(key) + end + + def self.maybe_run_sig_block_for_method(method) + maybe_run_sig_block_for_key(method_to_key(method)) + end + + # Only public so that it can be accessed in the closure for _on_method_added + def self.maybe_run_sig_block_for_key(key) + run_sig_block_for_key(key) if has_sig_block_for_key(key) + end + + def self.run_sig_block_for_method(method) + run_sig_block_for_key(method_to_key(method)) + end + + private_class_method def self.run_sig_block_for_key(key) + blk = @sig_wrappers[key] + if !blk + sig = @signatures_by_method[key] + if sig + # We already ran the sig block, perhaps in another thread. + return sig + else + raise "No `sig` wrapper for #{key_to_method(key)}" + end + end + + begin + sig = blk.call + rescue + @sigs_that_raised[key] = true + raise + end + if @sigs_that_raised[key] + raise "A previous invocation of #{key_to_method(key)} raised, and the current one succeeded. Please don't do that." + end + + @sig_wrappers.delete(key) + sig + end + + def self.run_all_sig_blocks + loop do + break if @sig_wrappers.empty? + key, = @sig_wrappers.first + run_sig_block_for_key(key) + end + end + + def self.all_checked_tests_sigs + @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 + # methods M on source, M is not defined on any of target's ancestors. + def self._hook_impl(target, singleton_class, source) + # we do not need to call add_was_ever_final here, because we have already marked + # any such methods when source was originally defined. + if !@modules_with_final.include?(target.object_id) + if !@modules_with_final.include?(source.object_id) + return + end + note_module_deals_with_final(target) + install_hooks(target) + return + end + + methods = source.instance_methods + methods.select! do |method_name| + @was_ever_final_names.include?(method_name) + end + if methods.empty? + return + end + + target_ancestors = singleton_class ? target.singleton_class.ancestors : target.ancestors + _check_final_ancestors(target, target_ancestors, methods, source) + end + + def self.set_final_checks_on_hooks(enable) + is_enabled = !@old_hooks.nil? + if enable == is_enabled + return + end + if is_enabled + @old_hooks.each(&:restore) + @old_hooks = nil + else + old_included = T::Private::ClassUtils.replace_method(Module, :included) do |arg| + old_included.bind(self).call(arg) + ::T::Private::Methods._hook_impl(arg, false, self) + end + old_extended = T::Private::ClassUtils.replace_method(Module, :extended) do |arg| + old_extended.bind(self).call(arg) + ::T::Private::Methods._hook_impl(arg, true, self) + end + old_inherited = T::Private::ClassUtils.replace_method(Class, :inherited) do |arg| + old_inherited.bind(self).call(arg) + ::T::Private::Methods._hook_impl(arg, false, self) + end + @old_hooks = [old_included, old_extended, old_inherited] + end + end + + module MethodHooks + def method_added(name) + super(name) + ::T::Private::Methods._on_method_added(self, name, is_singleton_method: false) + end + end + + module SingletonMethodHooks + def singleton_method_added(name) + super(name) + ::T::Private::Methods._on_method_added(self, name, is_singleton_method: true) + end + end + + def self.install_hooks(mod) + return if @installed_hooks.include?(mod) + @installed_hooks[mod] = true + + if mod == TOP_SELF + # self at the top-level of a file is weirdly special in Ruby + # The Ruby VM on startup creates an `Object.new` and stashes it. + # Unlike when we're using sig inside a module, `self` is actually a + # normal object, not an instance of Module. + # + # Thus we can't ask things like mod.singleton_class? (since that's + # defined only on Module, not on Object) and even if we could, the places + # where we need to install the hooks are special. + mod.extend(SingletonMethodHooks) # def self.foo; end (at top level) + Object.extend(MethodHooks) # def foo; end (at top level) + return + end + + # See https://github.com/sorbet/sorbet/pull/3964 for an explanation of why this + # check (which theoretically should not be needed) is actually needed. + if !mod.is_a?(Module) + return + end + + if mod.singleton_class? + mod.include(SingletonMethodHooks) + else + mod.extend(MethodHooks) + end + mod.extend(SingletonMethodHooks) + 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}" + end + + private_class_method def self.method_to_key(method) + method_owner_and_name_to_key(method.owner, method.name) + end + + private_class_method def self.key_to_method(key) + id, name = key.split("#") + obj = ObjectSpace._id2ref(id.to_i) + obj.instance_method(name) + end +end + +# This has to be here, and can't be nested inside `T::Private::Methods`, +# because the value of `self` depends on lexical (nesting) scope, and we +# specifically need a reference to the file-level self, i.e. `main:Object` +T::Private::Methods::TOP_SELF = self diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb new file mode 100644 index 0000000000..1889daa991 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb @@ -0,0 +1,221 @@ +# frozen_string_literal: true +# typed: false + +module T::Private::Methods::CallValidation + CallValidation = T::Private::Methods::CallValidation + Modes = T::Private::Methods::Modes + + # Wraps a method with a layer of validation for the given type signature. + # This wrapper is meant to be fast, and is applied by a previous wrapper, + # which was placed by `_on_method_added`. + # + # @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) + if method_sig.mode == T::Private::Methods::Modes.abstract + T::Private::ClassUtils.replace_method(mod, method_sig.method_name) do |*args, &blk| + # TODO: write a cop to ensure that abstract methods have an empty body + # + # We allow abstract methods to be implemented by things further down the ancestor chain. + # So, if a super method exists, call it. + if defined?(super) + super(*args, &blk) + else + raise NotImplementedError.new( + "The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation." + ) + end + end + # Do nothing in this case; this method was not wrapped in _on_method_added. + elsif method_sig.defined_raw + # Note, this logic is duplicated (intentionally, for micro-perf) at `Methods._on_method_added`, + # make sure to keep changes in sync. + # This is a trapdoor point for each method: + # if a given method is wrapped, it stays wrapped; and if not, it's never wrapped. + # (Therefore, we need the `@wrapped_tests_with_validation` check in `T::RuntimeLevels`.) + elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) + create_validator_method(mod, original_method, method_sig, original_visibility) + else + T::Configuration.without_ruby_warnings do + # get all the shims out of the way and put back the original method + T::Private::DeclState.current.without_on_method_added do + mod.send(:define_method, method_sig.method_name, original_method) + end + mod.send(original_visibility, method_sig.method_name) + end + end + # Return the newly created method (or the original one if we didn't replace it) + mod.instance_method(method_sig.method_name) + end + + @is_allowed_to_have_fast_path = true + def self.is_allowed_to_have_fast_path + @is_allowed_to_have_fast_path + end + + def self.disable_fast_path + @is_allowed_to_have_fast_path = false + end + + 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} + ok_for_fast_path = has_fixed_arity && !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)} + 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) + + T::Configuration.without_ruby_warnings do + T::Private::DeclState.current.without_on_method_added do + if simple_method + create_validator_method_fast(mod, original_method, method_sig) + elsif simple_procedure + create_validator_procedure_fast(mod, original_method, method_sig) + elsif ok_for_fast_path && method_sig.return_type.is_a?(T::Private::Types::Void) + create_validator_procedure_medium(mod, original_method, method_sig) + elsif ok_for_fast_path + create_validator_method_medium(mod, original_method, method_sig) + else + create_validator_slow(mod, original_method, method_sig) + end + end + end + mod.send(original_visibility, method_sig.method_name) + end + + def self.create_validator_slow(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |*args, &blk| + CallValidation.validate_call(self, original_method, method_sig, args, blk) + end + if mod.respond_to?(:ruby2_keywords, true) + mod.send(:ruby2_keywords, method_sig.method_name) + end + end + + def self.validate_call(instance, original_method, method_sig, args, blk) + # This method is called for every `sig`. It's critical to keep it fast and + # reduce number of allocations that happen here. + + if method_sig.bind + message = method_sig.bind.error_message_for_obj(instance) + if message + CallValidation.report_error( + method_sig, + message, + 'Bind', + nil, + method_sig.bind, + instance + ) + end + end + + # NOTE: We don't bother validating for missing or extra kwargs; + # the method call itself will take care of that. + method_sig.each_args_value_type(args) do |name, arg, type| + message = type.error_message_for_obj(arg) + if message + CallValidation.report_error( + method_sig, + message, + 'Parameter', + name, + type, + arg, + caller_offset: 2 + ) + end + end + + if method_sig.block_type + message = method_sig.block_type.error_message_for_obj(blk) + if message + CallValidation.report_error( + method_sig, + message, + 'Block parameter', + method_sig.block_name, + method_sig.block_type, + blk + ) + end + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = T::Configuration::AT_LEAST_RUBY_2_7 ? original_method.bind_call(instance, *args, &blk) : original_method.bind(instance).call(*args, &blk) + + # The only type that is allowed to change the return value is `.void`. + # It ignores what you returned and changes it to be a private singleton. + if method_sig.return_type.is_a?(T::Private::Types::Void) + T::Private::Types::Void::VOID + else + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + ) + end + return_value + end + end + + def self.report_error(method_sig, error_message, kind, name, type, value, caller_offset: 0) + caller_loc = T.must(caller_locations(3 + caller_offset, 1))[0] + definition_file, definition_line = method_sig.method.source_location + + pretty_message = "#{kind}#{name ? " '#{name}'" : ''}: #{error_message}\n" \ + "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" \ + "Definition: #{definition_file}:#{definition_line}" + + T::Configuration.call_validation_error_handler( + method_sig, + message: error_message, + pretty_message: pretty_message, + kind: kind, + name: name, + type: type, + value: value, + 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 + raise NameError.new("undefined method `#{name}` for `#{mod}`") + end + end +end + +if T::Configuration::AT_LEAST_RUBY_2_7 + require_relative './call_validation_2_7' +else + require_relative './call_validation_2_6' +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb new file mode 100644 index 0000000000..753580dc36 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb @@ -0,0 +1,1203 @@ +# frozen_string_literal: true +# typed: false + +# DO NOT EDIT. This file is autogenerated. To regenerate, run: +# +# bazel test //gems/sorbet-runtime:update_call_validation + +module T::Private::Methods::CallValidation + def self.create_validator_method_fast(mod, original_method, method_sig) + if method_sig.return_type.is_a?(T::Private::Types::Void) + raise 'Should have used create_validator_procedure_fast' + end + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type) + elsif method_sig.arg_types.length == 1 + create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type) + elsif method_sig.arg_types.length == 2 + create_validator_method_fast2(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type) + elsif method_sig.arg_types.length == 3 + create_validator_method_fast3(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type) + elsif method_sig.arg_types.length == 4 + create_validator_method_fast4(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type, + method_sig.arg_types[3][1].raw_type) + else + raise 'should not happen' + end + end + + def self.create_validator_method_fast0(mod, original_method, method_sig, return_type) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(&blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast1(mod, original_method, method_sig, return_type, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, arg2, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3.is_a?(arg3_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_procedure_fast(mod, original_method, method_sig) + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_procedure_fast0(mod, original_method, method_sig) + elsif method_sig.arg_types.length == 1 + create_validator_procedure_fast1(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type) + elsif method_sig.arg_types.length == 2 + create_validator_procedure_fast2(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type) + elsif method_sig.arg_types.length == 3 + create_validator_procedure_fast3(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type) + elsif method_sig.arg_types.length == 4 + create_validator_procedure_fast4(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type, + method_sig.arg_types[3][1].raw_type) + else + raise 'should not happen' + end + end + + def self.create_validator_procedure_fast0(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(&blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast1(mod, original_method, method_sig, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast2(mod, original_method, method_sig, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, arg2, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3.is_a?(arg3_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_method_medium(mod, original_method, method_sig) + if method_sig.return_type.is_a?(T::Private::Types::Void) + raise 'Should have used create_validator_procedure_medium' + end + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_method_medium0(mod, original_method, method_sig, method_sig.return_type) + elsif method_sig.arg_types.length == 1 + create_validator_method_medium1(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1]) + elsif method_sig.arg_types.length == 2 + create_validator_method_medium2(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1]) + elsif method_sig.arg_types.length == 3 + create_validator_method_medium3(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1]) + elsif method_sig.arg_types.length == 4 + create_validator_method_medium4(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1], + method_sig.arg_types[3][1]) + else + raise 'should not happen' + end + end + + def self.create_validator_method_medium0(mod, original_method, method_sig, return_type) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(&blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium1(mod, original_method, method_sig, return_type, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, arg2, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3_type.valid?(arg3) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_procedure_medium(mod, original_method, method_sig) + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_procedure_medium0(mod, original_method, method_sig) + elsif method_sig.arg_types.length == 1 + create_validator_procedure_medium1(mod, original_method, method_sig, + method_sig.arg_types[0][1]) + elsif method_sig.arg_types.length == 2 + create_validator_procedure_medium2(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1]) + elsif method_sig.arg_types.length == 3 + create_validator_procedure_medium3(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1]) + elsif method_sig.arg_types.length == 4 + create_validator_procedure_medium4(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1], + method_sig.arg_types[3][1]) + else + raise 'should not happen' + end + end + + def self.create_validator_procedure_medium0(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(&blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium1(mod, original_method, method_sig, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium2(mod, original_method, method_sig, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, arg2, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3_type.valid?(arg3) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) + T::Private::Types::Void::VOID + end + end + +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb new file mode 100644 index 0000000000..1686db8977 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb @@ -0,0 +1,1203 @@ +# frozen_string_literal: true +# typed: false + +# DO NOT EDIT. This file is autogenerated. To regenerate, run: +# +# bazel test //gems/sorbet-runtime:update_call_validation + +module T::Private::Methods::CallValidation + def self.create_validator_method_fast(mod, original_method, method_sig) + if method_sig.return_type.is_a?(T::Private::Types::Void) + raise 'Should have used create_validator_procedure_fast' + end + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type) + elsif method_sig.arg_types.length == 1 + create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type) + elsif method_sig.arg_types.length == 2 + create_validator_method_fast2(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type) + elsif method_sig.arg_types.length == 3 + create_validator_method_fast3(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type) + elsif method_sig.arg_types.length == 4 + create_validator_method_fast4(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type, + method_sig.arg_types[3][1].raw_type) + else + raise 'should not happen' + end + end + + def self.create_validator_method_fast0(mod, original_method, method_sig, return_type) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast1(mod, original_method, method_sig, return_type, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3.is_a?(arg3_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_procedure_fast(mod, original_method, method_sig) + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_procedure_fast0(mod, original_method, method_sig) + elsif method_sig.arg_types.length == 1 + create_validator_procedure_fast1(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type) + elsif method_sig.arg_types.length == 2 + create_validator_procedure_fast2(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type) + elsif method_sig.arg_types.length == 3 + create_validator_procedure_fast3(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type) + elsif method_sig.arg_types.length == 4 + create_validator_procedure_fast4(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type, + method_sig.arg_types[3][1].raw_type) + else + raise 'should not happen' + end + end + + def self.create_validator_procedure_fast0(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast1(mod, original_method, method_sig, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast2(mod, original_method, method_sig, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, arg2, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3.is_a?(arg3_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_method_medium(mod, original_method, method_sig) + if method_sig.return_type.is_a?(T::Private::Types::Void) + raise 'Should have used create_validator_procedure_medium' + end + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_method_medium0(mod, original_method, method_sig, method_sig.return_type) + elsif method_sig.arg_types.length == 1 + create_validator_method_medium1(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1]) + elsif method_sig.arg_types.length == 2 + create_validator_method_medium2(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1]) + elsif method_sig.arg_types.length == 3 + create_validator_method_medium3(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1]) + elsif method_sig.arg_types.length == 4 + create_validator_method_medium4(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1], + method_sig.arg_types[3][1]) + else + raise 'should not happen' + end + end + + def self.create_validator_method_medium0(mod, original_method, method_sig, return_type) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium1(mod, original_method, method_sig, return_type, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3_type.valid?(arg3) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_procedure_medium(mod, original_method, method_sig) + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_procedure_medium0(mod, original_method, method_sig) + elsif method_sig.arg_types.length == 1 + create_validator_procedure_medium1(mod, original_method, method_sig, + method_sig.arg_types[0][1]) + elsif method_sig.arg_types.length == 2 + create_validator_procedure_medium2(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1]) + elsif method_sig.arg_types.length == 3 + create_validator_procedure_medium3(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1]) + elsif method_sig.arg_types.length == 4 + create_validator_procedure_medium4(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1], + method_sig.arg_types[3][1]) + else + raise 'should not happen' + end + end + + def self.create_validator_procedure_medium0(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium1(mod, original_method, method_sig, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium2(mod, original_method, method_sig, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, arg2, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3_type.valid?(arg3) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) + T::Private::Types::Void::VOID + end + end + +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb new file mode 100644 index 0000000000..b48b1d5b68 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb @@ -0,0 +1,232 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Methods + Declaration = Struct.new(:mod, :params, :returns, :bind, :mode, :checked, :finalized, :on_failure, :override_allow_incompatible, :type_parameters, :raw) + + class DeclBuilder + attr_reader :decl + + class BuilderError < StandardError; end + + private def check_live! + if decl.finalized + raise BuilderError.new("You can't modify a signature declaration after it has been used.") + end + end + + def initialize(mod, raw) + # TODO RUBYPLAT-1278 - with ruby 2.5, use kwargs here + @decl = Declaration.new( + mod, + ARG_NOT_PROVIDED, # params + ARG_NOT_PROVIDED, # returns + ARG_NOT_PROVIDED, # bind + Modes.standard, # mode + ARG_NOT_PROVIDED, # checked + false, # finalized + ARG_NOT_PROVIDED, # on_failure + nil, # override_allow_incompatible + ARG_NOT_PROVIDED, # type_parameters + raw + ) + end + + def params(**params) + check_live! + if !decl.params.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .params twice") + end + + if params.empty? + raise BuilderError.new("params expects keyword arguments") + end + decl.params = params + + self + end + + def returns(type) + check_live! + if decl.returns.is_a?(T::Private::Types::Void) + raise BuilderError.new("You can't call .returns after calling .void.") + end + if !decl.returns.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .returns multiple times in a signature.") + end + + decl.returns = type + + self + end + + def void + check_live! + if !decl.returns.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .void after calling .returns.") + end + + decl.returns = T::Private::Types::Void.new + + self + end + + def bind(type) + check_live! + if !decl.bind.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .bind multiple times in a signature.") + end + + decl.bind = type + + self + end + + def checked(level) + check_live! + + if !decl.checked.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .checked multiple times in a signature.") + end + if (level == :never || level == :compiled) && !decl.on_failure.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't use .checked(:#{level}) with .on_failure because .on_failure will have no effect.") + end + if !T::Private::RuntimeLevels::LEVELS.include?(level) + raise BuilderError.new("Invalid `checked` level '#{level}'. Use one of: #{T::Private::RuntimeLevels::LEVELS}.") + end + + decl.checked = level + + self + end + + def on_failure(*args) + check_live! + + if !decl.on_failure.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .on_failure multiple times in a signature.") + end + if decl.checked == :never || decl.checked == :compiled + raise BuilderError.new("You can't use .on_failure with .checked(:#{decl.checked}) because .on_failure will have no effect.") + end + + decl.on_failure = args + + self + end + + def abstract + check_live! + + case decl.mode + when Modes.standard + decl.mode = Modes.abstract + when Modes.abstract + raise BuilderError.new(".abstract cannot be repeated in a single signature") + else + raise BuilderError.new("`.abstract` cannot be combined with `.override` or `.overridable`.") + end + + self + end + + def final + check_live! + raise BuilderError.new("The syntax for declaring a method final is `sig(:final) {...}`, not `sig {final. ...}`") + end + + def override(allow_incompatible: false) + check_live! + + case decl.mode + when Modes.standard + decl.mode = Modes.override + decl.override_allow_incompatible = allow_incompatible + when Modes.override, Modes.overridable_override + raise BuilderError.new(".override cannot be repeated in a single signature") + when Modes.overridable + decl.mode = Modes.overridable_override + else + raise BuilderError.new("`.override` cannot be combined with `.abstract`.") + end + + self + end + + def overridable + check_live! + + case decl.mode + when Modes.abstract + raise BuilderError.new("`.overridable` cannot be combined with `.#{decl.mode}`") + when Modes.override + decl.mode = Modes.overridable_override + when Modes.standard + decl.mode = Modes.overridable + when Modes.overridable, Modes.overridable_override + raise BuilderError.new(".overridable cannot be repeated in a single signature") + end + + self + end + + # Declares valid type paramaters which can be used with `T.type_parameter` in + # this `sig`. + # + # This is used for generic methods. Example usage: + # + # sig do + # type_parameters(:U) + # .params(blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U))) + # .returns(T::Array[T.type_parameter(:U)]) + # end + # def map(&blk); end + def type_parameters(*names) + check_live! + + names.each do |name| + raise BuilderError.new("not a symbol: #{name}") unless name.is_a?(Symbol) + end + + if !decl.type_parameters.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .type_parameters multiple times in a signature.") + end + + decl.type_parameters = names + + self + end + + def finalize! + check_live! + + if decl.returns.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You must provide a return type; use the `.returns` or `.void` builder methods.") + end + + if decl.bind.equal?(ARG_NOT_PROVIDED) + decl.bind = nil + end + if decl.checked.equal?(ARG_NOT_PROVIDED) + default_checked_level = T::Private::RuntimeLevels.default_checked_level + if (default_checked_level == :never || default_checked_level == :compiled) && !decl.on_failure.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("To use .on_failure you must additionally call .checked(:tests) or .checked(:always), otherwise, the .on_failure has no effect.") + end + decl.checked = default_checked_level + end + if decl.on_failure.equal?(ARG_NOT_PROVIDED) + decl.on_failure = nil + end + if decl.params.equal?(ARG_NOT_PROVIDED) + decl.params = {} + end + if decl.type_parameters.equal?(ARG_NOT_PROVIDED) + decl.type_parameters = {} + end + + decl.finalized = true + + self + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb new file mode 100644 index 0000000000..53d9a93195 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Methods::Modes + def self.standard + 'standard' + end + def self.abstract + 'abstract' + end + def self.overridable + 'overridable' + end + def self.override + 'override' + end + def self.overridable_override + 'overridable_override' + end + def self.untyped + 'untyped' + end + MODES = [self.standard, self.abstract, self.overridable, self.override, self.overridable_override, self.untyped].freeze + + OVERRIDABLE_MODES = [self.override, self.overridable, self.overridable_override, self.untyped, self.abstract].freeze + OVERRIDE_MODES = [self.override, self.overridable_override].freeze + NON_OVERRIDE_MODES = MODES - OVERRIDE_MODES +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb new file mode 100644 index 0000000000..bd15977bd5 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb @@ -0,0 +1,225 @@ +# frozen_string_literal: true +# typed: true + +class T::Private::Methods::Signature + attr_reader :method, :method_name, :arg_types, :kwarg_types, :block_type, :block_name, + :rest_type, :rest_name, :keyrest_type, :keyrest_name, :bind, + :return_type, :mode, :req_arg_count, :req_kwarg_names, :has_rest, :has_keyrest, + :check_level, :parameters, :on_failure, :override_allow_incompatible, + :defined_raw + + def self.new_untyped(method:, mode: T::Private::Methods::Modes.untyped, parameters: method.parameters) + # Using `Untyped` ensures we'll get an error if we ever try validation on these. + not_typed = T::Private::Types::NotTyped.new + raw_return_type = not_typed + # Map missing parameter names to "argN" positionally + parameters = parameters.each_with_index.map do |(param_kind, param_name), index| + [param_kind, param_name || "arg#{index}"] + end + raw_arg_types = parameters.map do |_param_kind, param_name| + [param_name, not_typed] + end.to_h + + self.new( + method: method, + method_name: method.name, + raw_arg_types: raw_arg_types, + raw_return_type: raw_return_type, + bind: nil, + mode: mode, + check_level: :never, + parameters: parameters, + on_failure: nil, + ) + end + + def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false, defined_raw: false) + @method = method + @method_name = method_name + @arg_types = [] + @kwarg_types = {} + @block_type = nil + @block_name = nil + @rest_type = nil + @rest_name = nil + @keyrest_type = nil + @keyrest_name = nil + @return_type = T::Utils.coerce(raw_return_type) + @bind = bind ? T::Utils.coerce(bind) : bind + @mode = mode + @check_level = check_level + @req_arg_count = 0 + @req_kwarg_names = [] + @has_rest = false + @has_keyrest = false + @parameters = parameters + @on_failure = on_failure + @override_allow_incompatible = override_allow_incompatible + @defined_raw = defined_raw + + declared_param_names = raw_arg_types.keys + # If sig params are declared but there is a single parameter with a missing name + # **and** the method ends with a "=", assume it is a writer method generated + # by attr_writer or attr_accessor + writer_method = declared_param_names != [nil] && parameters == [[:req]] && 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 + param_names = parameters.map {|_, name| name} + missing_names = param_names - declared_param_names + extra_names = declared_param_names - param_names + if !missing_names.empty? + raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}" + end + if !extra_names.empty? + raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}" + end + + if parameters.size != raw_arg_types.size + raise "The declaration for `#{method.name}` has arguments with duplicate names" + end + + parameters.zip(raw_arg_types) do |(param_kind, param_name), (type_name, raw_type)| + if type_name != param_name + hint = "" + # Ruby reorders params so that required keyword arguments + # 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} + 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." + end + + raise "Parameter `#{type_name}` is declared out of order (declared as arg number " \ + "#{declared_param_names.index(type_name) + 1}, defined in the method as arg number " \ + "#{param_names.index(type_name) + 1}).#{hint}\nMethod: #{method_desc}" + end + + type = T::Utils.coerce(raw_type) + + case param_kind + when :req + if @arg_types.length > @req_arg_count + # Note that this is actually is supported by Ruby, but it would add complexity to + # support it here, and I'm happy to discourage its use anyway. + # + # If you are seeing this error and surprised by it, it's possible that you have + # overridden the method described in the error message. For example, Rails defines + # def self.update!(id = :all, attributes) + # on AR models. If you have also defined `self.update!` on an AR model you might + # see this error. The simplest resolution is to rename your method. + raise "Required params after optional params are not supported in method declarations. Method: #{method_desc}" + end + @arg_types << [param_name, type] + @req_arg_count += 1 + when :opt + @arg_types << [param_name, type] + when :key, :keyreq + @kwarg_types[param_name] = type + if param_kind == :keyreq + @req_kwarg_names << param_name + end + when :block + @block_name = param_name + @block_type = type + when :rest + @has_rest = true + @rest_name = param_name + @rest_type = type + when :keyrest + @has_keyrest = true + @keyrest_name = param_name + @keyrest_type = type + else + raise "Unexpected param_kind: `#{param_kind}`. Method: #{method_desc}" + end + end + end + + attr_writer :method_name + protected :method_name= + + def as_alias(alias_name) + new_sig = clone + new_sig.method_name = alias_name + new_sig + end + + def arg_count + @arg_types.length + end + + def kwarg_names + @kwarg_types.keys + end + + def owner + @method.owner + end + + def dsl_method + "#{@mode}_method" + end + + # @return [Hash] a mapping like `{arg_name: [val, type], ...}`, for only those args actually present. + def each_args_value_type(args) + # Manually split out args and kwargs based on ruby's behavior. Do not try to implement this by + # getting ruby to determine the kwargs for you (e.g., by defining this method to take *args and + # **kwargs). That won't work, because ruby's behavior for determining kwargs is dependent on the + # the other parameters in the method definition, and our method definition here doesn't (and + # can't) match the definition of the method we're validating. In addition, Ruby has a bug that + # causes forwarding **kwargs to do the wrong thing: see https://bugs.ruby-lang.org/issues/10708 + # and https://bugs.ruby-lang.org/issues/11860. + args_length = args.length + if (args_length > @req_arg_count) && (!@kwarg_types.empty? || @has_keyrest) && args[-1].is_a?(Hash) + kwargs = args[-1] + args_length -= 1 + else + kwargs = EMPTY_HASH + end + + arg_types = @arg_types + + if @has_rest + rest_count = args_length - @arg_types.length + rest_count = 0 if rest_count.negative? + + arg_types += [[@rest_name, @rest_type]] * rest_count + + elsif (args_length < @req_arg_count) || (args_length > @arg_types.length) + expected_str = @req_arg_count.to_s + if @arg_types.length != @req_arg_count + expected_str += "..#{@arg_types.length}" + end + raise ArgumentError.new("wrong number of arguments (given #{args_length}, expected #{expected_str})") + end + + begin + it = 0 + while it < args_length + yield arg_types[it][0], args[it], arg_types[it][1] + it += 1 + end + end + + kwargs.each do |name, val| + type = @kwarg_types[name] + if !type && @has_keyrest + type = @keyrest_type + end + yield name, val, type if type + end + end + + def method_desc + loc = if @method.source_location + @method.source_location.join(':') + else + "" + end + "#{@method} at #{loc}" + end + + EMPTY_HASH = {}.freeze +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb new file mode 100644 index 0000000000..16188e0bf3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb @@ -0,0 +1,225 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Methods::SignatureValidation + Methods = T::Private::Methods + Modes = Methods::Modes + + def self.validate(signature) + if signature.method_name == :initialize && signature.method.owner.is_a?(Class) + # Constructors are special. They look like overrides in terms of a super_method existing, + # but in practice, you never call them polymorphically. Conceptually, they're standard + # methods (this is consistent with how they're treated in other languages, e.g. Java) + if signature.mode != Modes.standard + raise "`initialize` should not use `.abstract` or `.implementation` or any other inheritance modifiers." + end + return + end + + super_method = signature.method.super_method + + if super_method && super_method.owner != signature.method.owner + Methods.maybe_run_sig_block_for_method(super_method) + super_signature = Methods.signature_for_method(super_method) + + # 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? + nil + else + # super_signature can be nil when we're overriding a method (perhaps a builtin) that didn't use + # one of the method signature helpers. Use an untyped signature so we can still validate + # everything but types. + # + # We treat these signatures as overridable, that way people can use `.override` with + # overrides of builtins. In the future we could try to distinguish when the method is a + # builtin and treat non-builtins as non-overridable (so you'd be forced to declare them with + # `.overridable`). + # + super_signature ||= Methods::Signature.new_untyped(method: super_method) + + validate_override_mode(signature, super_signature) + validate_override_shape(signature, super_signature) + validate_override_types(signature, super_signature) + end + else + validate_non_override_mode(signature) + end + end + + private_class_method def self.pretty_mode(signature) + if signature.mode == Modes.overridable_override + '.overridable.override' + else + ".#{signature.mode}" + end + end + + def self.validate_override_mode(signature, super_signature) + case signature.mode + when *Modes::OVERRIDE_MODES + # Peaceful + when *Modes::NON_OVERRIDE_MODES + if super_signature.mode == Modes.standard + # Peaceful + elsif super_signature.mode == Modes.abstract + raise "You must use `.override` when overriding the abstract method `#{signature.method_name}`.\n" \ + " Abstract definition: #{method_loc_str(super_signature.method)}\n" \ + " Implementation definition: #{method_loc_str(signature.method)}\n" + elsif super_signature.mode != Modes.untyped + raise "You must use `.override` when overriding the existing method `#{signature.method_name}`.\n" \ + " Parent definition: #{method_loc_str(super_signature.method)}\n" \ + " Child definition: #{method_loc_str(signature.method)}\n" + end + else + raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + end + + def self.validate_non_override_mode(signature) + case signature.mode + when Modes.override + if signature.method_name == :each && signature.method.owner < Enumerable + # Enumerable#each is the only method in Sorbet's RBI payload that defines an abstract method. + # Enumerable#each does not actually exist at runtime, but it is required to be implemented by + # any class which includes Enumerable. We want to declare Enumerable#each as abstract so that + # people can call it anything which implements the Enumerable interface, and so that it's a + # static error to forget to implement it. + # + # This is a one-off hack, and we should think carefully before adding more methods here. + nil + else + raise "You marked `#{signature.method_name}` as #{pretty_mode(signature)}, but that method doesn't already exist in this class/module to be overriden.\n" \ + " Either check for typos and for missing includes or super classes to make the parent method shows up\n" \ + " ... or remove #{pretty_mode(signature)} here: #{method_loc_str(signature.method)}\n" + end + when Modes.standard, *Modes::NON_OVERRIDE_MODES + # Peaceful + nil + else + raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + + # Given a singleton class, we can check if it belongs to a + # module by looking at its superclass; given `module M`, + # `M.singleton_class.superclass == Module`, which is not true + # for any class. + owner = signature.method.owner + if (signature.mode == Modes.abstract || Modes::OVERRIDABLE_MODES.include?(signature.mode)) && + owner.singleton_class? && owner.superclass == Module + raise "Defining an overridable class method (via #{pretty_mode(signature)}) " \ + "on a module is not allowed. Class methods on " \ + "modules do not get inherited and thus cannot be overridden." + end + end + + def self.validate_override_shape(signature, super_signature) + return if signature.override_allow_incompatible + return if super_signature.mode == Modes.untyped + + method_name = signature.method_name + mode_verb = super_signature.mode == Modes.abstract ? 'implements' : 'overrides' + + if !signature.has_rest && signature.arg_count < super_signature.arg_count + raise "Your definition of `#{method_name}` must accept at least #{super_signature.arg_count} " \ + "positional arguments to be compatible with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + if !signature.has_rest && super_signature.has_rest + raise "Your definition of `#{method_name}` must have `*#{super_signature.rest_name}` " \ + "to be compatible with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + if signature.req_arg_count > super_signature.req_arg_count + raise "Your definition of `#{method_name}` must have no more than #{super_signature.req_arg_count} " \ + "required argument(s) to be compatible with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + if !signature.has_keyrest + # O(nm), but n and m are tiny here + missing_kwargs = super_signature.kwarg_names - signature.kwarg_names + if !missing_kwargs.empty? + raise "Your definition of `#{method_name}` is missing these keyword arg(s): #{missing_kwargs} " \ + "which are defined in the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + end + + if !signature.has_keyrest && super_signature.has_keyrest + raise "Your definition of `#{method_name}` must have `**#{super_signature.keyrest_name}` " \ + "to be compatible with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + # O(nm), but n and m are tiny here + extra_req_kwargs = signature.req_kwarg_names - super_signature.req_kwarg_names + if !extra_req_kwargs.empty? + raise "Your definition of `#{method_name}` has extra required keyword arg(s) " \ + "#{extra_req_kwargs} relative to the method it #{mode_verb}, making it incompatible: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + if super_signature.block_name && !signature.block_name + raise "Your definition of `#{method_name}` must accept a block parameter to be compatible " \ + "with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + end + + def self.validate_override_types(signature, super_signature) + return if signature.override_allow_incompatible + return if super_signature.mode == Modes.untyped + return unless [signature, super_signature].all? do |sig| + sig.check_level == :always || sig.check_level == :compiled || (sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) + end + mode_noun = super_signature.mode == Modes.abstract ? 'implementation' : 'override' + + # arg types must be contravariant + super_signature.arg_types.zip(signature.arg_types).each_with_index do |((_super_name, super_type), (name, type)), index| + if !super_type.subtype_of?(type) + raise "Incompatible type for arg ##{index + 1} (`#{name}`) in signature for #{mode_noun} of method " \ + "`#{signature.method_name}`:\n" \ + "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \ + "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \ + "(The types must be contravariant.)" + end + end + + # kwarg types must be contravariant + super_signature.kwarg_types.each do |name, super_type| + type = signature.kwarg_types[name] + if !super_type.subtype_of?(type) + raise "Incompatible type for arg `#{name}` in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \ + "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \ + "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \ + "(The types must be contravariant.)" + end + end + + # return types must be covariant + if !signature.return_type.subtype_of?(super_signature.return_type) + raise "Incompatible return type in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \ + "* Base: `#{super_signature.return_type}` (in #{method_loc_str(super_signature.method)})\n" \ + "* #{mode_noun.capitalize}: `#{signature.return_type}` (in #{method_loc_str(signature.method)})\n" \ + "(The types must be covariant.)" + end + 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)}" \ + "\n * #{mode_noun}: in #{method_loc_str(signature.method)}" + end + + private_class_method def self.method_loc_str(method) + loc = if method.source_location + method.source_location.join(':') + else + "" + end + "#{method.owner} at #{loc}" + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb new file mode 100644 index 0000000000..01eb42bd3a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true +# typed: true + +module T::Private + module MixesInClassMethods + def included(other) + mods = Abstract::Data.get(self, :class_methods_mixins) + mods.each {|mod| other.extend(mod)} + super + end + end + + module Mixins + def self.declare_mixes_in_class_methods(mixin, class_methods) + if mixin.is_a?(Class) + raise "Classes cannot be used as mixins, and so mixes_in_class_methods cannot be used on a Class." + end + + if Abstract::Data.key?(mixin, :class_methods_mixins) + class_methods = Abstract::Data.get(mixin, :class_methods_mixins) + class_methods + end + + mixin.singleton_class.include(MixesInClassMethods) + Abstract::Data.set(mixin, :class_methods_mixins, class_methods) + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb new file mode 100644 index 0000000000..7b2822d394 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Retry + + # A special singleton used for static analysis of exceptions. + module RETRY + freeze + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb new file mode 100644 index 0000000000..2454b21988 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true +# typed: true + +# Used in `sig.checked(level)` to determine when runtime type checking +# is enabled on a method. +module T::Private::RuntimeLevels + LEVELS = [ + # Validate every call in every environment + :always, + # Validate in tests, but not in production + :tests, + # Don't even validate in tests, b/c too expensive, + # or b/c we fully trust the static typing + :never, + # Validate the sig when the file is using the Sorbet Compiler. + # Behaves like :never when interpreted. + :compiled, + ].freeze + + @check_tests = false + @wrapped_tests_with_validation = false + + @has_read_default_checked_level = false + @default_checked_level = :always + + def self.check_tests? + # Assume that this code path means that some `sig.checked(:tests)` + # has been wrapped (or not wrapped) already, which is a trapdoor + # for toggling `@check_tests`. + @wrapped_tests_with_validation = true + + @check_tests + end + + 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- ") + raise "Toggle `:tests`-level runtime type checking earlier. " \ + "There are already some methods wrapped with `sig.checked(:tests)`:\n" \ + "- #{locations}" + end + + _toggle_checking_tests(true) + end + + def self.default_checked_level + @has_read_default_checked_level = true + @default_checked_level + end + + def self.default_checked_level=(default_checked_level) + if @has_read_default_checked_level + raise "Set the default checked level earlier. There are already some methods whose sig blocks have evaluated which would not be affected by the new default." + end + @default_checked_level = default_checked_level + end + + def self._toggle_checking_tests(checked) + @check_tests = checked + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb new file mode 100644 index 0000000000..62e19fb088 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true +# typed: false + +module T::Private::Sealed + module NoInherit + def inherited(child) + super + this_line = Kernel.caller.find {|line| !line.match(/in `inherited'$/)} + T::Private::Sealed.validate_inheritance(this_line, self, child, 'inherited') + @sorbet_sealed_module_all_subclasses << child + end + + def sealed_subclasses + @sorbet_sealed_module_all_subclasses_set ||= # rubocop:disable Naming/MemoizedInstanceVariableName + begin + require 'set' + Set.new(@sorbet_sealed_module_all_subclasses).freeze + end + end + end + + module NoIncludeExtend + def included(child) + super + this_line = Kernel.caller.find {|line| !line.match(/in `included'$/)} + T::Private::Sealed.validate_inheritance(this_line, self, child, 'included') + @sorbet_sealed_module_all_subclasses << child + end + + def extended(child) + super + this_line = Kernel.caller.find {|line| !line.match(/in `extended'$/)} + T::Private::Sealed.validate_inheritance(this_line, self, child, 'extended') + @sorbet_sealed_module_all_subclasses << child + end + + def sealed_subclasses + # this will freeze the set so that you can never get into a + # state where you use the subclasses list and then something + # else will add to it + @sorbet_sealed_module_all_subclasses_set ||= # rubocop:disable Naming/MemoizedInstanceVariableName + begin + require 'set' + Set.new(@sorbet_sealed_module_all_subclasses).freeze + end + end + end + + def self.declare(mod, decl_file) + if !mod.is_a?(Module) + raise "#{mod} is not a class or module and cannot be declared `sealed!`" + end + if sealed_module?(mod) + raise "#{mod} was already declared `sealed!` and cannot be re-declared `sealed!`" + end + if T::Private::Final.final_module?(mod) + raise "#{mod} was already declared `final!` and cannot be declared `sealed!`" + end + mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend) + if !decl_file + raise "Couldn't determine declaration file for sealed class." + end + mod.instance_variable_set(:@sorbet_sealed_module_decl_file, decl_file) + mod.instance_variable_set(:@sorbet_sealed_module_all_subclasses, []) + end + + def self.sealed_module?(mod) + mod.instance_variable_defined?(:@sorbet_sealed_module_decl_file) + end + + def self.validate_inheritance(this_line, parent, child, verb) + this_file = this_line&.split(':')&.first + decl_file = parent.instance_variable_get(:@sorbet_sealed_module_decl_file) if sealed_module?(parent) + + if !this_file + raise "Could not use backtrace to determine file for #{verb} child #{child}" + end + if !decl_file + raise "#{parent} does not seem to be a sealed module (#{verb} by #{child})" + end + + if !this_file.start_with?(decl_file) + whitelist = T::Configuration.sealed_violation_whitelist + if !whitelist.nil? && whitelist.any? {|pattern| this_file =~ pattern} + return + end + + raise "#{parent} was declared sealed and can only be #{verb} in #{decl_file}, not #{this_file}" + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb new file mode 100644 index 0000000000..57196553b6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# typed: true + +# A placeholder for when an untyped thing must provide a type. +# Raises an exception if it is ever used for validation. +class T::Private::Types::NotTyped < T::Types::Base + ERROR_MESSAGE = "Validation is being done on a `NotTyped`. Please report this bug at https://github.com/sorbet/sorbet/issues" + + # overrides Base + def name + "" + end + + # overrides Base + def valid?(obj) + raise ERROR_MESSAGE + end + + # overrides Base + private def subtype_of_single?(other) + raise ERROR_MESSAGE + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb new file mode 100644 index 0000000000..b2295f7730 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true +# typed: true + +# Holds a string. Useful for showing type aliases in error messages +class T::Private::Types::StringHolder < T::Types::Base + attr_reader :string + + def initialize(string) + @string = string + end + + # overrides Base + def name + string + end + + # overrides Base + def valid?(obj) + false + end + + # overrides Base + private def subtype_of_single?(other) + false + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb new file mode 100644 index 0000000000..de805c9659 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Types + # Wraps a proc for a type alias to defer its evaluation. + class TypeAlias < T::Types::Base + + def initialize(callable) + @callable = callable + end + + def aliased_type + @aliased_type ||= T::Utils.coerce(@callable.call) + end + + # overrides Base + def name + aliased_type.name + end + + # overrides Base + def recursively_valid?(obj) + aliased_type.recursively_valid?(obj) + end + + # overrides Base + def valid?(obj) + aliased_type.valid?(obj) + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb new file mode 100644 index 0000000000..310fc56abc --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true +# typed: true + +# A marking class for when methods return void. +# Should never appear in types directly. +class T::Private::Types::Void < T::Types::Base + ERROR_MESSAGE = "Validation is being done on an `Void`. Please report this bug at https://github.com/sorbet/sorbet/issues" + + # The actual return value of `.void` methods. + # + # Uses `module VOID` because this gives it a readable name when someone + # examines it in Pry or with `#inspect` like: + # + # T::Private::Types::Void::VOID + # + module VOID + freeze + end + + # overrides Base + def name + "" + end + + # overrides Base + def valid?(obj) + raise ERROR_MESSAGE + end + + # overrides Base + private def subtype_of_single?(other) + raise ERROR_MESSAGE + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb new file mode 100644 index 0000000000..fae252aa04 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb @@ -0,0 +1,169 @@ +# frozen_string_literal: true +# typed: true + +# A mixin for defining typed properties (attributes). +# To get serialization methods (to/from JSON-style hashes), add T::Props::Serializable. +# To get a constructor based on these properties, inherit from T::Struct. +module T::Props + extend T::Helpers + + ##### + # CAUTION: This mixin is used in hundreds of classes; we want to keep its surface area as narrow + # as possible and avoid polluting (and possibly conflicting with) the classes that use it. + # + # It currently has *zero* instance methods; let's try to keep it that way. + # For ClassMethods (below), try to add things to T::Props::Decorator instead unless you are sure + # it needs to be exposed here. + ##### + + module ClassMethods + extend T::Sig + extend T::Helpers + + def props + decorator.props + end + def plugins + @plugins ||= [] + end + + def decorator_class + Decorator + end + + def decorator + @decorator ||= decorator_class.new(self) + end + def reload_decorator! + @decorator = decorator_class.new(self) + end + + # Define a new property. See {file:README.md} for some concrete + # examples. + # + # Defining a property defines a method with the same name as the + # property, that returns the current value, and a `prop=` method + # to set its value. Properties will be inherited by subclasses of + # a document class. + # + # @param name [Symbol] The name of this property + # @param cls [Class,T::Types::Base] The type of this + # property. If the type is itself a `Document` subclass, this + # property will be recursively serialized/deserialized. + # @param rules [Hash] Options to control this property's behavior. + # @option rules [T::Boolean,Symbol] :optional If `true`, this property + # is never required to be set before an instance is serialized. + # If `:on_load` (default), when this property is missing or nil, a + # new model cannot be saved, and an existing model can only be + # saved if the property was already missing when it was loaded. + # If `false`, when the property is missing/nil after deserialization, it + # will be set to the default value (as defined by the `default` or + # `factory` option) or will raise if they are not present. + # Deprecated: For `Model`s, if `:optional` is set to the special value + # `:existing`, the property can be saved as nil even if it was + # deserialized with a non-nil value. (Deprecated because there should + # never be a need for this behavior; the new behavior of non-optional + # properties should be sufficient.) + # @option rules [Array] :enum An array of legal values; The + # property is required to take on one of those values. + # @option rules [T::Boolean] :dont_store If true, this property will + # not be saved on the hash resulting from + # {T::Props::Serializable#serialize} + # @option rules [Object] :ifunset A value to be returned if this + # property is requested but has never been set (is set to + # `nil`). It is applied at property-access time, and never saved + # back onto the object or into the database. + # + # ``:ifunset`` is considered **DEPRECATED** and should not be used + # in new code, in favor of just setting a default value. + # @option rules [Model, Symbol, Proc] :foreign A model class that this + # property is a reference to. Passing `:foreign` will define a + # `:"#{name}_"` method, that will load and return the + # corresponding foreign model. + # + # A symbol can be passed to avoid load-order dependencies; It + # will be lazily resolved relative to the enclosing module of the + # defining class. + # + # A callable (proc or method) can be passed to dynamically specify the + # foreign model. This will be passed the object instance so that other + # properties of the object can be used to determine the relevant model + # class. It should return a string/symbol class name or the foreign model + # class directly. + # + # @option rules [Object] :default A default value that will be set + # by `#initialize` if none is provided in the initialization + # hash. This will not affect objects loaded by {.from_hash}. + # @option rules [Proc] :factory A `Proc` that will be called to + # generate an initial value for this prop on `#initialize`, if + # none is provided. + # @option rules [T::Boolean] :immutable If true, this prop cannot be + # modified after an instance is created or loaded from a hash. + # @option rules [T::Boolean] :override It is an error to redeclare a + # `prop` that has already been declared (including on a + # superclass), unless `:override` is set to `true`. + # @option rules [Symbol, Array] :redaction A redaction directive that may + # be passed to Chalk::Tools::RedactionUtils.redact_with_directive to + # sanitize this parameter for display. Will define a + # `:"#{name}_redacted"` method, which will return the value in sanitized + # form. + # + # @return [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) + end + + # Validates the value of the specified prop. This method allows the caller to + # validate a value for a prop without having to set the data on the instance. + # Throws if invalid. + # + # @param prop [Symbol] + # @param val [Object] + # @return [void] + def validate_prop_value(prop, val) + decorator.validate_prop_value(prop, val) + end + + # Needs to be documented + def plugin(mod) + decorator.plugin(mod) + end + + # Shorthand helper to define a `prop` with `immutable => true` + sig {params(name: Symbol, cls_or_args: T.untyped, args: T::Hash[Symbol, 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") + end + + if cls_or_args.is_a?(Hash) + self.prop(name, cls_or_args.merge(immutable: true)) + else + self.prop(name, cls_or_args, args.merge(immutable: true)) + end + end + + def included(child) + decorator.model_inherited(child) + super + end + + def prepended(child) + decorator.model_inherited(child) + super + end + + def extended(child) + decorator.model_inherited(child.singleton_class) + super + end + + def inherited(child) + decorator.model_inherited(child) + super + end + end + mixes_in_class_methods(ClassMethods) +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb new file mode 100644 index 0000000000..570c068ac4 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::Constructor + include T::Props::WeakConstructor +end + +module T::Props::Constructor::DecoratorMethods + extend T::Sig + + # Set values for all props that have no defaults. Override what `WeakConstructor` + # does in order to raise errors on nils instead of ignoring them. + # + # @return [Integer] A count of props that we successfully initialized (which + # 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)} + 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. + result = 0 + props_without_defaults&.each_pair do |p, setter_proc| + begin + val = hash[p] + instance.instance_exec(val, &setter_proc) + if val || hash.key?(p) + result += 1 + end + rescue TypeError, T::Props::InvalidValueError + if !hash.key?(p) + raise ArgumentError.new("Missing required prop `#{p}` for class `#{instance.class.name}`") + else + raise + end + end + end + result + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb new file mode 100644 index 0000000000..0df6a0d863 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module CustomType + extend T::Sig + extend T::Helpers + + abstract! + + include Kernel # for `is_a?` + + # Alias for backwards compatibility + sig(:final) do + params( + value: BasicObject, + ) + .returns(T::Boolean) + .checked(:never) + end + def instance?(value) + self.===(value) + end + + # Alias for backwards compatibility + sig(:final) do + params( + value: BasicObject, + ) + .returns(T::Boolean) + .checked(:never) + end + def valid?(value) + instance?(value) + end + + # Given an instance of this type, serialize that into a scalar type + # supported by 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)} + def serialize(instance); end + + # Given the serialized form of your type, this returns an instance + # of that custom type representing that value. + # + # @param scalar One of T::Configuration.scalar_types + # @return Object + sig {abstract.params(scalar: T.untyped).returns(T.untyped).checked(:never)} + def deserialize(scalar); end + + 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: Object).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 + # are all classes. + klass = T.let(val.class, T.nilable(Class)) + until klass.nil? + return true if T::Configuration.scalar_types.include?(klass.to_s) + klass = klass.superclass + end + false + end + + # We allow custom types to serialize to Arrays, so that we can + # 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)} + def self.valid_serialization?(val) + case val + when Array + val.each do |v| + return false unless scalar_type?(v) + end + + true + else + scalar_type?(val) + end + end + + sig(:final) do + params(instance: Object) + .returns(T.untyped) + .checked(:never) + end + def self.checked_serialize(instance) + val = T.cast(instance.class, T::Props::CustomType).serialize(instance) + unless valid_serialization?(val) + msg = "#{instance.class} did not serialize to a valid scalar type. It became a: #{val.class}" + if val.is_a?(Hash) + msg += "\nIf you want to store a structured Hash, consider using a T::Struct as your type." + end + raise TypeError.new(msg) + end + val + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb new file mode 100644 index 0000000000..679a32584b --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb @@ -0,0 +1,669 @@ +# frozen_string_literal: true +# typed: strict + +# NB: This is not actually a decorator. It's just named that way for consistency +# with DocumentDecorator and ModelDecorator (which both seem to have been written +# with an incorrect understanding of the decorator pattern). These "decorators" +# should really just be static methods on private modules (we'd also want/need to +# replace decorator overrides in plugins with class methods that expose the necessary +# functionality). +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)} + + class NoRulesError < StandardError; end + + EMPTY_PROPS = T.let({}.freeze, T::Hash[Symbol, Rules]) + private_constant :EMPTY_PROPS + + 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| + T::Props::Plugin::Private.apply_decorator_methods(mod, self) + end + @props = T.let(EMPTY_PROPS, T::Hash[Symbol, Rules]) + end + + # checked(:never) - O(prop accesses) + sig {returns(T::Hash[Symbol, Rules]).checked(:never)} + attr_reader :props + + 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)} + 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)} + def add_prop_definition(prop, rules) + override = rules.delete(:override) + + if props.include?(prop) && !override + raise ArgumentError.new("Attempted to redefine prop #{prop.inspect} that's already defined without specifying :override => true: #{prop_rules(prop)}") + elsif !props.include?(prop) && override + raise ArgumentError.new("Attempted to override a prop #{prop.inspect} that doesn't already exist") + end + + @props = @props.merge(prop => rules.freeze).freeze + end + + # Heads up! + # + # There are already too many ad-hoc options on the prop DSL. + # + # We have already done a lot of work to remove unnecessary and confusing + # options. If you're considering adding a new rule key, please come chat with + # the Sorbet team first, as we'd really like to learn more about how to best + # solve the problem you're encountering. + VALID_RULE_KEYS = T.let(%i[ + enum + foreign + ifunset + immutable + override + redaction + sensitivity + without_accessors + clobber_existing_method! + extra + setter_validate + _tnilable + ].map {|k| [k, true]}.to_h.freeze, T::Hash[Symbol, T::Boolean]) + private_constant :VALID_RULE_KEYS + + 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)} + def decorated_class + @class + end + + # Accessors + + # 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)} + def validate_prop_value(prop, val) + # We call `setter_proc` here without binding to an instance, so it'll run + # `instance_variable_set` if validation passes, but nothing will care. + # We only care about the validation. + prop_rules(prop).fetch(:setter_proc).call(val) + end + + # For performance, don't use named params here. + # Passing in rules here is purely a performance optimization. + # Unlike the other methods that take rules, this one calls prop_rules for + # the default, which raises if the prop doesn't exist (this maintains + # preexisting behavior). + # + # Note this path is NOT used by generated setters on instances, + # which are defined using `setter_proc` directly. + # + # checked(:never) - O(prop accesses) + sig do + params( + instance: DecoratedInstance, + prop: Symbol, + val: T.untyped, + rules: Rules + ) + .void + .checked(:never) + end + def prop_set(instance, prop, val, rules=prop_rules(prop)) + instance.instance_exec(val, &rules.fetch(:setter_proc)) + end + alias_method :set, :prop_set + + # Only Models have any custom get logic but we need to call this on + # non-Models since we don't know at code gen time what we have. + sig do + params( + instance: DecoratedInstance, + prop: Symbol, + value: T.untyped + ) + .returns(T.untyped) + .checked(:never) + end + def prop_get_logic(instance, prop, value) + value + end + + # For performance, don't use named params here. + # Passing in rules here is purely a performance optimization. + # + # Note this path is NOT used by generated getters on instances, + # unless `ifunset` is used on the prop, or `prop_get` is overridden. + # + # checked(:never) - O(prop accesses) + sig do + params( + instance: DecoratedInstance, + prop: T.any(String, Symbol), + rules: Rules + ) + .returns(T.untyped) + .checked(:never) + end + def prop_get(instance, prop, rules=prop_rules(prop)) + val = instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key]) + if !val.nil? + val + elsif (d = rules[:ifunset]) + T::Props::Utils.deep_clone_object(d) + else + nil + end + end + + sig do + params( + instance: DecoratedInstance, + prop: T.any(String, Symbol), + rules: Rules + ) + .returns(T.untyped) + .checked(:never) + end + def prop_get_if_set(instance, prop, rules=prop_rules(prop)) + instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key]) + end + alias_method :get, :prop_get_if_set # Alias for backwards compatibility + + # checked(:never) - O(prop accesses) + sig do + params( + instance: DecoratedInstance, + prop: Symbol, + foreign_class: Module, + rules: Rules, + opts: T::Hash[Symbol, T.untyped], + ) + .returns(T.untyped) + .checked(:never) + end + def foreign_prop_get(instance, prop, foreign_class, rules=prop_rules(prop), opts={}) + return if !(value = prop_get(instance, prop, rules)) + T.unsafe(foreign_class).load(value, {}, opts) + 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(:never) - Rules hash is expensive to check + sig do + params( + name: Symbol, + cls: Module, + rules: Rules, + type: PropTypeOrClass + ) + .void + .checked(:never) + end + def prop_validate_definition!(name, cls, rules, type) + validate_prop_name(name) + + if rules.key?(:pii) + raise ArgumentError.new("The 'pii:' option for props has been renamed " \ + "to 'sensitivity:' (in prop #{@class.name}.#{name})") + end + + 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 + + if !rules[:clobber_existing_method!] && !rules[:without_accessors] && BANNED_METHOD_NAMES.include?(name.to_sym) + raise ArgumentError.new( + "#{name} can't be used as a prop in #{@class} because a method with " \ + "that name already exists (defined by #{@class.instance_method(name).owner} " \ + "at #{@class.instance_method(name).source_location || ''}). " \ + "(If using this name is unavoidable, try `without_accessors: true`.)" + ) + end + + extra = rules[:extra] + if !extra.nil? && !extra.is_a?(Hash) + raise ArgumentError.new("Extra metadata must be a Hash in prop #{@class.name}.#{name}") + end + + nil + end + + SAFE_NAME = T.let(/\A[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp) + + # Used to validate both prop names and serialized forms + sig {params(name: T.any(Symbol, String)).void} + private def validate_prop_name(name) + if !name.match?(SAFE_NAME) + raise ArgumentError.new("Invalid prop name in #{@class.name}: #{name}") + end + end + + # This converts the type from a T::Type to a regular old ruby class. + sig {params(type: T::Types::Base).returns(Module)} + private def convert_type_to_class(type) + case type + when T::Types::TypedArray, T::Types::FixedArray + Array + when T::Types::TypedHash, T::Types::FixedHash + Hash + when T::Types::TypedSet + Set + when T::Types::Union + # The below unwraps our T.nilable types for T::Props if we can. + # This lets us do things like specify: const T.nilable(String), foreign: Opus::DB::Model::Merchant + non_nil_type = T::Utils.unwrap_nilable(type) + if non_nil_type + convert_type_to_class(non_nil_type) + else + Object + end + when T::Types::Simple + type.raw_type + else + # This isn't allowed unless whitelisted_for_underspecification is + # true, due to the check in prop_validate_definition + Object + end + end + + # Returns `true` when the type of the prop is nilable, or the field is typed + # as `T.untyped`, a `:default` is present in the rules hash, and its value is + # `nil`. The latter case is a workaround for explicitly not supporting the use + # of `T.nilable(T.untyped)`. + # + # checked(:never) - Rules hash is expensive to check + sig do + params( + cls: PropTypeOrClass, + rules: Rules, + ) + .void + .checked(:never) + end + private def prop_nilable?(cls, rules) + T::Utils::Nilable.is_union_with_nilclass(cls) || (cls == T.untyped && rules.key?(:default) && rules[:default].nil?) + end + + # checked(:never) - Rules hash is expensive to check + sig do + params( + name: T.any(Symbol, String), + cls: PropTypeOrClass, + rules: Rules, + ) + .void + .checked(:never) + end + def prop_defined(name, cls, rules={}) + cls = T::Utils.resolve_alias(cls) + + if prop_nilable?(cls, rules) + # :_tnilable is introduced internally for performance purpose so that clients do not need to call + # T::Utils::Nilable.is_tnilable(cls) again. + # It is strictly internal: clients should always use T::Props::Utils.required_prop?() or + # T::Props::Utils.optional_prop?() for checking whether a field is required or optional. + rules[:_tnilable] = true + end + + name = name.to_sym + type = cls + if !cls.is_a?(Module) + cls = convert_type_to_class(cls) + end + type_object = smart_coerce(type, enum: rules[:enum]) + + prop_validate_definition!(name, cls, rules, type_object) + + # Retrive the possible underlying object with T.nilable. + type = T::Utils::Nilable.get_underlying_type(type) + + sensitivity_and_pii = {sensitivity: rules[:sensitivity]} + normalize = T::Configuration.normalize_sensitivity_and_pii_handler + if normalize + sensitivity_and_pii = normalize.call(sensitivity_and_pii) + + # We check for Class so this is only applied on concrete + # documents/models; We allow mixins containing props to not + # specify their PII nature, as long as every class into which they + # are ultimately included does. + # + if sensitivity_and_pii[:pii] && @class.is_a?(Class) && !T.unsafe(@class).contains_pii? + raise ArgumentError.new( + 'Cannot include a pii prop in a class that declares `contains_no_pii`' + ) + end + end + + rules = rules.merge( + # TODO: The type of this element is confusing. We should refactor so that + # it can be always `type_object` (a PropType) or always `cls` (a Module) + type: type, + type_object: type_object, + accessor_key: "@#{name}".to_sym, + sensitivity: sensitivity_and_pii[:sensitivity], + pii: sensitivity_and_pii[:pii], + # extra arbitrary metadata attached by the code defining this property + extra: rules[:extra]&.freeze, + ) + + validate_not_missing_sensitivity(name, rules) + + # for backcompat (the `:array` key is deprecated but because the name is + # so generic it's really hard to be sure it's not being relied on anymore) + if type.is_a?(T::Types::TypedArray) + inner = T::Utils::Nilable.get_underlying_type(type.type) + if inner.is_a?(Module) + rules[:array] = inner + end + end + + rules[:setter_proc] = T::Props::Private::SetterFactory.build_setter_proc(@class, name, rules).freeze + + add_prop_definition(name, rules) + + # NB: using `without_accessors` doesn't make much sense unless you also define some other way to + # get at the property (e.g., Chalk::ODM::Document exposes `get` and `set`). + define_getter_and_setter(name, rules) unless rules[:without_accessors] + + handle_foreign_option(name, cls, rules, rules[:foreign]) if rules[:foreign] + handle_redaction_option(name, rules[:redaction]) if rules[:redaction] + end + + # checked(:never) - Rules hash is expensive to check + 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] + if method(:prop_set).owner != T::Props::Decorator + @class.send(:define_method, "#{name}=") do |val| + T.unsafe(self.class).decorator.prop_set(self, name, val, rules) + end + else + # Fast path (~4x faster as of Ruby 2.6) + @class.send(:define_method, "#{name}=", &rules.fetch(:setter_proc)) + end + end + + if method(:prop_get).owner != T::Props::Decorator || rules.key?(:ifunset) + @class.send(:define_method, name) do + T.unsafe(self.class).decorator.prop_get(self, name, rules) + end + else + # Fast path (~30x faster as of Ruby 2.6) + @class.send(:attr_reader, name) # send is used because `attr_reader` is private in 2.4 + end + end + end + + sig do + params(type: PropTypeOrClass, enum: T.untyped) + .returns(T::Types::Base) + end + private def smart_coerce(type, enum:) + # Backwards compatibility for pre-T::Types style + type = T::Utils.coerce(type) + if enum.nil? + type + else + nonnil_type = T::Utils.unwrap_nilable(type) + if nonnil_type + T.unsafe(T.nilable(T.all(nonnil_type, T.deprecated_enum(enum)))) + else + T.unsafe(T.all(T.unsafe(type), T.deprecated_enum(enum))) + end + end + end + + # checked(:never) - Rules hash is expensive to check + 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] + T::Configuration.hard_assert_handler( + "#{@class}##{prop_name} has a 'redaction:' annotation but no " \ + "'sensitivity:' annotation. This is probably wrong, because if a " \ + "prop needs redaction then it is probably sensitive. Add a " \ + "sensitivity annotation like 'sensitivity: Opus::Sensitivity::PII." \ + "whatever', or explicitly override this check with 'sensitivity: []'." + ) + end + # TODO(PRIVACYENG-982) Ideally we'd also check for 'password' and possibly + # other terms, but this interacts badly with ProtoDefinedDocument because + # the proto syntax currently can't declare "sensitivity: []" + if /\bsecret\b/.match?(prop_name) + T::Configuration.hard_assert_handler( + "#{@class}##{prop_name} has the word 'secret' in its name, but no " \ + "'sensitivity:' annotation. This is probably wrong, because if a " \ + "prop is named 'secret' then it is probably sensitive. Add a " \ + "sensitivity annotation like 'sensitivity: Opus::Sensitivity::NonPII." \ + "security_token', or explicitly override this check with " \ + "'sensitivity: []'." + ) + end + end + end + + # Create `#{prop_name}_redacted` method + sig do + params( + prop_name: Symbol, + redaction: T.untyped, + ) + .void + end + private def handle_redaction_option(prop_name, redaction) + redacted_method = "#{prop_name}_redacted" + + @class.send(:define_method, redacted_method) do + value = self.public_send(prop_name) + handler = T::Configuration.redaction_handler + if !handler + raise "Using `redaction:` on a prop requires specifying `T::Configuration.redaction_handler`" + end + handler.call(value, redaction) + end + end + + sig do + params( + option_sym: Symbol, + foreign: T.untyped, + valid_type_msg: String, + ) + .void + end + private def validate_foreign_option(option_sym, foreign, valid_type_msg:) + if foreign.is_a?(Symbol) || foreign.is_a?(String) + raise ArgumentError.new( + "Using a symbol/string for `#{option_sym}` is no longer supported. Instead, use a Proc " \ + "that returns the class, e.g., foreign: -> {Foo}" + ) + end + + if !foreign.is_a?(Proc) && !foreign.is_a?(Array) && !foreign.respond_to?(:load) + raise ArgumentError.new("The `#{option_sym}` option must be #{valid_type_msg}") + end + end + + # checked(:never) - Rules hash is expensive to check + sig do + params( + prop_name: T.any(String, Symbol), + rules: Rules, + foreign: T.untyped, + ) + .void + .checked(:never) + end + private def define_foreign_method(prop_name, rules, foreign) + fk_method = "#{prop_name}_" + + # n.b. there's no clear reason *not* to allow additional options + # here, but we're baking in `allow_direct_mutation` since we + # *haven't* allowed additional options in the past and want to + # default to keeping this interface narrow. + @class.send(:define_method, fk_method) do |allow_direct_mutation: nil| + foreign = T.let(foreign, T.untyped) + if foreign.is_a?(Proc) + resolved_foreign = foreign.call + if !resolved_foreign.respond_to?(:load) + raise ArgumentError.new( + "The `foreign` proc for `#{prop_name}` must return a model class. " \ + "Got `#{resolved_foreign.inspect}` instead." + ) + end + # `foreign` is part of the closure state, so this will persist to future invocations + # of the method, optimizing it so this only runs on the first invocation. + foreign = resolved_foreign + end + opts = if allow_direct_mutation.nil? + {} + else + {allow_direct_mutation: allow_direct_mutation} + end + + T.unsafe(self.class).decorator.foreign_prop_get(self, prop_name, foreign, rules, opts) + end + + force_fk_method = "#{fk_method}!" + @class.send(:define_method, force_fk_method) do |allow_direct_mutation: nil| + loaded_foreign = send(fk_method, allow_direct_mutation: allow_direct_mutation) + if !loaded_foreign + T::Configuration.hard_assert_handler( + 'Failed to load foreign model', + storytime: {method: force_fk_method, class: self.class} + ) + end + loaded_foreign + end + end + + # checked(:never) - Rules hash is expensive to check + sig do + params( + prop_name: Symbol, + prop_cls: Module, + rules: Rules, + foreign: T.untyped, + ) + .void + .checked(:never) + end + private def handle_foreign_option(prop_name, prop_cls, rules, foreign) + validate_foreign_option( + :foreign, foreign, valid_type_msg: "a model class or a Proc that returns one" + ) + + if prop_cls != String + raise ArgumentError.new("`foreign` can only be used with a prop type of String") + end + + if foreign.is_a?(Array) + # We don't support arrays with `foreign` because it's hard to both preserve ordering and + # keep them from being lurky performance hits by issuing a bunch of un-batched DB queries. + # We could potentially address that by porting over something like AmbiguousIDLoader. + raise ArgumentError.new( + "Using an array for `foreign` is no longer supported. Instead, please use a union type of " \ + "token types for the prop type, e.g., T.any(Opus::Autogen::Tokens::FooModelToken, Opus::Autogen::Tokens::BarModelToken)" + ) + end + + unless foreign.is_a?(Proc) + T::Configuration.soft_assert_handler(<<~MESSAGE, storytime: {prop: prop_name, value: foreign}, notify: 'jerry') + Please use a Proc that returns a model class instead of the model class itself as the argument to `foreign`. In other words: + + instead of `prop :foo, String, foreign: FooModel` + use `prop :foo, String, foreign: -> {FooModel}` + + MESSAGE + end + + define_foreign_method(prop_name, rules, foreign) + end + + # TODO: rename this to props_inherited + # + # 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)} + def model_inherited(child) + child.extend(T::Props::ClassMethods) + child = T.cast(child, T.all(Module, T::Props::ClassMethods)) + + child.plugins.concat(decorated_class.plugins) + decorated_class.plugins.each do |mod| + # NB: apply_class_methods must not be an instance method on the decorator itself, + # otherwise we'd have to call child.decorator here, which would create the decorator + # before any `decorator_class` override has a chance to take effect (see the comment below). + T::Props::Plugin::Private.apply_class_methods(mod, child) + end + + props.each do |name, rules| + copied_rules = rules.dup + # NB: Calling `child.decorator` here is a timb bomb that's going to give someone a really bad + # time. Any class that defines props and also overrides the `decorator_class` method is going + # to reach this line before its override take effect, turning it into a no-op. + child.decorator.add_prop_definition(name, copied_rules) + + # It's a bit tricky to support `prop_get` hooks added by plugins without + # sacrificing the `attr_reader` fast path or clobbering customized getters + # defined manually on a child. + # + # To make this work, we _do_ clobber getters defined on the child, but only if: + # (a) it's needed in order to support a `prop_get` hook, and + # (b) it's safe because the getter was defined by this file. + # + unless rules[:without_accessors] + if clobber_getter?(child, name) + child.send(:define_method, name) do + T.unsafe(self.class).decorator.prop_get(self, name, rules) + end + end + + if !rules[:immutable] && clobber_setter?(child, name) + child.send(:define_method, "#{name}=") do |val| + T.unsafe(self.class).decorator.prop_set(self, name, val, rules) + end + end + end + end + end + + 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)} + 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)} + def plugin(mod) + decorated_class.plugins << mod + T::Props::Plugin::Private.apply_class_methods(mod, decorated_class) + T::Props::Plugin::Private.apply_decorator_methods(mod, self) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb new file mode 100644 index 0000000000..6977f20471 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + class Error < StandardError; end + class InvalidValueError < Error; end + class ImmutableProp < Error; end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb new file mode 100644 index 0000000000..91f256799d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb @@ -0,0 +1,277 @@ +# frozen_string_literal: true +# typed: true + +module T::Props + # Helper to validate generated code, to mitigate security concerns around + # `class_eval`. Not called by default; the expectation is this will be used + # in a test iterating over all T::Props::Serializable subclasses. + # + # We validate the exact expected structure of the generated methods as far + # as we can, and then where cloning produces an arbitrarily nested structure, + # we just validate a lack of side effects. + module GeneratedCodeValidation + extend Private::Parse + + class ValidationError < RuntimeError; end + + def self.validate_deserialize(source) + parsed = parse(source) + + # def %(hash) + # ... + # end + assert_equal(:def, parsed.type) + name, args, body = parsed.children + assert_equal(:__t_props_generated_deserialize, name) + assert_equal(s(:args, s(:arg, :hash)), args) + + assert_equal(:begin, body.type) + init, *prop_clauses, ret = body.children + + # found = % + # ... + # found + assert_equal(:lvasgn, init.type) + init_name, init_val = init.children + assert_equal(:found, init_name) + assert_equal(:int, init_val.type) + assert_equal(s(:lvar, :found), ret) + + prop_clauses.each_with_index do |clause, i| + if i.even? + validate_deserialize_hash_read(clause) + else + validate_deserialize_ivar_set(clause) + end + end + end + + def self.validate_serialize(source) + parsed = parse(source) + + # def %(strict) + # ... + # end + assert_equal(:def, parsed.type) + name, args, body = parsed.children + assert_equal(:__t_props_generated_serialize, name) + assert_equal(s(:args, s(:arg, :strict)), args) + + assert_equal(:begin, body.type) + init, *prop_clauses, ret = body.children + + # h = {} + # ... + # h + assert_equal(s(:lvasgn, :h, s(:hash)), init) + assert_equal(s(:lvar, :h), ret) + + prop_clauses.each do |clause| + validate_serialize_clause(clause) + end + end + + private_class_method def self.validate_serialize_clause(clause) + assert_equal(:if, clause.type) + condition, if_body, else_body = clause.children + + # if @%.nil? + assert_equal(:send, condition.type) + receiver, method = condition.children + assert_equal(:ivar, receiver.type) + assert_equal(:nil?, method) + + unless if_body.nil? + # required_prop_missing_from_serialize(%) if strict + assert_equal(:if, if_body.type) + if_strict_condition, if_strict_body, if_strict_else = if_body.children + assert_equal(s(:lvar, :strict), if_strict_condition) + assert_equal(:send, if_strict_body.type) + on_strict_receiver, on_strict_method, on_strict_arg = if_strict_body.children + assert_equal(nil, on_strict_receiver) + assert_equal(:required_prop_missing_from_serialize, on_strict_method) + assert_equal(:sym, on_strict_arg.type) + assert_equal(nil, if_strict_else) + end + + # h[%] = ... + assert_equal(:send, else_body.type) + receiver, method, h_key, h_val = else_body.children + assert_equal(s(:lvar, :h), receiver) + assert_equal(:[]=, method) + assert_equal(:str, h_key.type) + + validate_lack_of_side_effects(h_val, whitelisted_methods_for_serialize) + end + + private_class_method def self.validate_deserialize_hash_read(clause) + # val = hash[%s] + + assert_equal(:lvasgn, clause.type) + name, val = clause.children + assert_equal(:val, name) + assert_equal(:send, val.type) + receiver, method, arg = val.children + assert_equal(s(:lvar, :hash), receiver) + assert_equal(:[], method) + assert_equal(:str, arg.type) + end + + private_class_method def self.validate_deserialize_ivar_set(clause) + # %s = if val.nil? + # found -= 1 unless hash.key?(%s) + # %s + # else + # %s + # end + + assert_equal(:ivasgn, clause.type) + ivar_name, deser_val = clause.children + unless ivar_name.is_a?(Symbol) + raise ValidationError.new("Unexpected ivar: #{ivar_name}") + end + + assert_equal(:if, deser_val.type) + condition, if_body, else_body = deser_val.children + assert_equal(s(:send, s(:lvar, :val), :nil?), condition) + + assert_equal(:begin, if_body.type) + update_found, handle_nil = if_body.children + assert_equal(:if, update_found.type) + found_condition, found_if_body, found_else_body = update_found.children + assert_equal(:send, found_condition.type) + receiver, method, arg = found_condition.children + assert_equal(s(:lvar, :hash), receiver) + assert_equal(:key?, method) + assert_equal(:str, arg.type) + assert_equal(nil, found_if_body) + assert_equal(s(:op_asgn, s(:lvasgn, :found), :-, s(:int, 1)), found_else_body) + + validate_deserialize_handle_nil(handle_nil) + + if else_body.type == :kwbegin + rescue_expression, = else_body.children + assert_equal(:rescue, rescue_expression.type) + + try, rescue_body = rescue_expression.children + validate_lack_of_side_effects(try, whitelisted_methods_for_deserialize) + + 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)} + assert_equal(:lvasgn, assignment.type) + assert_equal([:e], assignment.children) + + deserialization_error, val_return = handler.children + + assert_equal(:send, deserialization_error.type) + 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)} + + validate_lack_of_side_effects(val_return, whitelisted_methods_for_deserialize) + else + validate_lack_of_side_effects(else_body, whitelisted_methods_for_deserialize) + end + end + + private_class_method def self.validate_deserialize_handle_nil(node) + case node.type + when :hash, :array, :str, :sym, :int, :float, :true, :false, :nil, :const # rubocop:disable Lint/BooleanSymbol + # Primitives and constants are safe + when :send + receiver, method, arg = node.children + if receiver.nil? + # required_prop_missing_from_deserialize(%) + assert_equal(:required_prop_missing_from_deserialize, method) + assert_equal(:sym, arg.type) + elsif receiver == self_class_decorator + # self.class.decorator.raise_nil_deserialize_error(%) + assert_equal(:raise_nil_deserialize_error, method) + assert_equal(:str, arg.type) + elsif method == :default + # self.class.decorator.props_with_defaults.fetch(%).default + assert_equal(:send, receiver.type) + inner_receiver, inner_method, inner_arg = receiver.children + assert_equal( + s(:send, self_class_decorator, :props_with_defaults), + inner_receiver, + ) + assert_equal(:fetch, inner_method) + assert_equal(:sym, inner_arg.type) + else + raise ValidationError.new("Unexpected receiver in nil handler: #{node.inspect}") + end + else + raise ValidationError.new("Unexpected nil handler: #{node.inspect}") + end + end + + private_class_method def self.self_class_decorator + @self_class_decorator ||= s(:send, s(:send, s(:self), :class), :decorator).freeze + end + + private_class_method def self.validate_lack_of_side_effects(node, whitelisted_methods_by_receiver_type) + case node.type + when :const + # This is ok, because we'll have validated what method has been called + # if applicable + when :hash, :array, :str, :sym, :int, :float, :true, :false, :nil, :self # rubocop:disable Lint/BooleanSymbol + # Primitives & self are ok + when :lvar, :arg, :ivar + # Reading local & instance variables & arguments is ok + 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} + when :send + # Sends are riskier so check a whitelist + receiver, method, *args = node.children + if receiver + if receiver.type == :send + key = receiver + else + key = receiver.type + validate_lack_of_side_effects(receiver, whitelisted_methods_by_receiver_type) + end + + if !whitelisted_methods_by_receiver_type[key]&.include?(method) + raise ValidationError.new("Unexpected method #{method} called on #{receiver.inspect}") + end + end + args.each do |arg| + validate_lack_of_side_effects(arg, whitelisted_methods_by_receiver_type) + end + else + raise ValidationError.new("Unexpected node type #{node.type}: #{node.inspect}") + end + end + + private_class_method def self.assert_equal(expected, actual) + if expected != actual + raise ValidationError.new("Expected #{expected}, got #{actual}") + end + end + + # Method calls generated by SerdeTransform + private_class_method def self.whitelisted_methods_for_serialize + @whitelisted_methods_for_serialize ||= { + lvar: %i{dup map transform_values transform_keys each_with_object nil? []= serialize}, + ivar: %i[dup map transform_values transform_keys each_with_object serialize], + const: %i[checked_serialize deep_clone_object], + } + end + + # Method calls generated by SerdeTransform + private_class_method def self.whitelisted_methods_for_deserialize + @whitelisted_methods_for_deserialize ||= { + lvar: %i{dup map transform_values transform_keys each_with_object nil? []= to_f}, + const: %i[deserialize from_hash deep_clone_object], + } + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb new file mode 100644 index 0000000000..5c1acecb69 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb @@ -0,0 +1,140 @@ +# frozen_string_literal: true +# typed: false + +module T::Props + + # Helper for generating methods that replace themselves with a specialized + # version on first use. The main use case is when we want to generate a + # method using the full set of props on a class; we can't do that during + # prop definition because we have no way of knowing whether we are defining + # the last prop. + # + # See go/M8yrvzX2 (Stripe-internal) for discussion of security considerations. + # In outline, while `class_eval` is a bit scary, we believe that as long as + # all inputs are defined in version control (and this is enforced by calling + # `disable_lazy_evaluation!` appropriately), risk isn't significantly higher + # than with build-time codegen. + module HasLazilySpecializedMethods + extend T::Sig + + class SourceEvaluationDisabled < RuntimeError + def initialize + super("Evaluation of lazily-defined methods is disabled") + end + end + + # Disable any future evaluation of lazily-defined methods. + # + # This is intended to be called after startup but before interacting with + # the outside world, to limit attack surface for our `class_eval` use. + # + # Note it does _not_ prevent explicit calls to `eagerly_define_lazy_methods!` + # from working. + sig {void} + def self.disable_lazy_evaluation! + @lazy_evaluation_disabled ||= true + end + + sig {returns(T::Boolean)} + def self.lazy_evaluation_enabled? + !defined?(@lazy_evaluation_disabled) || !@lazy_evaluation_disabled + end + + module DecoratorMethods + extend T::Sig + + 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)} + private def lazily_defined_vm_methods + @lazily_defined_vm_methods ||= {} + end + + sig {params(name: Symbol).void} + private def eval_lazily_defined_method!(name) + if !HasLazilySpecializedMethods.lazy_evaluation_enabled? + raise SourceEvaluationDisabled.new + end + + source = lazily_defined_methods.fetch(name).call + + cls = decorated_class + cls.class_eval(source.to_s) + cls.send(:private, name) + end + + sig {params(name: Symbol).void} + private def eval_lazily_defined_vm_method!(name) + if !HasLazilySpecializedMethods.lazy_evaluation_enabled? + raise SourceEvaluationDisabled.new + end + + lazily_defined_vm_methods.fetch(name).call + + cls = decorated_class + cls.send(:private, name) + end + + sig {params(name: Symbol, blk: T.proc.returns(String)).void} + private def enqueue_lazy_method_definition!(name, &blk) + lazily_defined_methods[name] = blk + + cls = decorated_class + if cls.method_defined?(name) + # Ruby does not emit "method redefined" warnings for aliased methods + # (more robust than undef_method that would create a small window in which the method doesn't exist) + cls.send(:alias_method, name, name) + end + cls.send(:define_method, name) do |*args| + self.class.decorator.send(:eval_lazily_defined_method!, name) + send(name, *args) + end + if cls.respond_to?(:ruby2_keywords, true) + cls.send(:ruby2_keywords, name) + end + cls.send(:private, name) + end + + sig {params(name: Symbol, blk: T.untyped).void} + private def enqueue_lazy_vm_method_definition!(name, &blk) + lazily_defined_vm_methods[name] = blk + + cls = decorated_class + cls.send(:define_method, name) do |*args| + self.class.decorator.send(:eval_lazily_defined_vm_method!, name) + send(name, *args) + end + if cls.respond_to?(:ruby2_keywords, true) + cls.send(:ruby2_keywords, name) + end + cls.send(:private, name) + end + + sig {void} + def eagerly_define_lazy_methods! + return if lazily_defined_methods.empty? + + source = lazily_defined_methods.values.map(&:call).map(&:to_s).join("\n\n") + + cls = decorated_class + cls.class_eval(source) + lazily_defined_methods.each_key {|name| cls.send(:private, name)} + lazily_defined_methods.clear + end + + 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.clear + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb new file mode 100644 index 0000000000..4f482beac3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::Optional + include T::Props::Plugin +end + +############################################## + +# NB: This must stay in the same file where T::Props::Optional is defined due to +# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 +module T::Props::Optional::DecoratorMethods + extend T::Sig + + # Heads up! + # + # There are already too many ad-hoc options on the prop DSL. + # + # We have already done a lot of work to remove unnecessary and confusing + # options. If you're considering adding a new rule key, please come chat with + # the Sorbet team first, as we'd really like to learn more about how to best + # solve the problem you're encountering. + VALID_RULE_KEYS = { + default: true, + factory: true, + }.freeze + private_constant :VALID_RULE_KEYS + + DEFAULT_SETTER_RULE_KEY = :_t_props_private_apply_default + private_constant :DEFAULT_SETTER_RULE_KEY + + def valid_rule_key?(key) + super || VALID_RULE_KEYS[key] + end + + def prop_optional?(prop) + prop_rules(prop)[:fully_optional] + end + + def compute_derived_rules(rules) + rules[:fully_optional] = !T::Props::Utils.need_nil_write_check?(rules) + rules[:need_nil_read_check] = T::Props::Utils.need_nil_read_check?(rules) + end + + # checked(:never) - O(runtime object construction) + 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)} + attr_reader :props_without_defaults + + def add_prop_definition(prop, rules) + compute_derived_rules(rules) + + default_setter = T::Props::Private::ApplyDefault.for(decorated_class, rules) + if default_setter + @props_with_defaults ||= {} + @props_with_defaults[prop] = default_setter + props_without_defaults&.delete(prop) # Handle potential override + + rules[DEFAULT_SETTER_RULE_KEY] = default_setter + else + @props_without_defaults ||= {} + @props_without_defaults[prop] = rules.fetch(:setter_proc) + props_with_defaults&.delete(prop) # Handle potential override + end + + super + end + + def prop_validate_definition!(name, cls, rules, type) + result = super + + if rules.key?(:default) && rules.key?(:factory) + raise ArgumentError.new("Setting both :default and :factory is invalid. See: go/chalk-docs") + end + + result + end + + def has_default?(rules) + rules.include?(DEFAULT_SETTER_RULE_KEY) + end + + def get_default(rules, instance_class) + rules[DEFAULT_SETTER_RULE_KEY]&.default + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb new file mode 100644 index 0000000000..1423c172ed --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::Plugin + include T::Props + extend T::Helpers + + module ClassMethods + def included(child) + super + child.plugin(self) + end + end + mixes_in_class_methods(ClassMethods) + + module Private + # These need to be non-instance methods so we can use them without prematurely creating the + # child decorator in `model_inherited` (see comments there for details). + # + # The dynamic constant access below forces this file to be `typed: false` + def self.apply_class_methods(plugin, target) + if plugin.const_defined?('ClassMethods') + # FIXME: This will break preloading, selective test execution, etc if `mod::ClassMethods` + # is ever defined in a separate file from `mod`. + target.extend(plugin::ClassMethods) + end + end + + def self.apply_decorator_methods(plugin, target) + if plugin.const_defined?('DecoratorMethods') + # FIXME: This will break preloading, selective test execution, etc if `mod::DecoratorMethods` + # is ever defined in a separate file from `mod`. + target.extend(plugin::DecoratorMethods) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb new file mode 100644 index 0000000000..e821cd3435 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true +# typed: true + +module T::Props::PrettyPrintable + include T::Props::Plugin + + # Return a string representation of this object and all of its props + def inspect + T.unsafe(T.cast(self, Object).class).decorator.inspect_instance(self) + end + + # Override the PP gem with something that's similar, but gives us a hook + # to do redaction + def pretty_inspect + T.unsafe(T.cast(self, Object).class).decorator.inspect_instance(self, multiline: true) + end + + module DecoratorMethods + extend T::Sig + + sig {params(key: Symbol).returns(T::Boolean).checked(:never)} + def valid_rule_key?(key) + super || key == :inspect + end + + sig do + params(instance: T::Props::PrettyPrintable, multiline: T::Boolean, indent: String) + .returns(String) + end + def inspect_instance(instance, multiline: false, indent: ' ') + components = + inspect_instance_components( + instance, + multiline: multiline, + indent: indent + ) + .reject(&:empty?) + + # Not using #<> here as that makes pry highlight these objects + # as if they were all comments, whereas this makes them look + # like the structured thing they are. + if multiline + "#{components[0]}:\n" + T.must(components[1..-1]).join("\n") + else + "<#{components.join(' ')}>" + end + end + + sig do + params(instance: T::Props::PrettyPrintable, multiline: T::Boolean, indent: String) + .returns(T::Array[String]) + end + private def inspect_instance_components(instance, multiline:, indent:) + pretty_props = T.unsafe(self).all_props.map do |prop| + [prop, inspect_prop_value(instance, prop, multiline: multiline, indent: indent)] + end + + joined_props = join_props_with_pretty_values( + pretty_props, + multiline: multiline, + indent: indent + ) + + [ + T.unsafe(self).decorated_class.to_s, + joined_props, + ] + end + + sig do + params(instance: T::Props::PrettyPrintable, prop: Symbol, multiline: T::Boolean, indent: String) + .returns(String) + .checked(:never) + end + private def inspect_prop_value(instance, prop, multiline:, indent:) + val = T.unsafe(self).get(instance, prop) + rules = T.unsafe(self).prop_rules(prop) + if (custom_inspect = rules[:inspect]) + if T::Utils.arity(custom_inspect) == 1 + custom_inspect.call(val) + else + custom_inspect.call(val, {multiline: multiline, indent: indent}) + end + elsif rules[:sensitivity] && !rules[:sensitivity].empty? && !val.nil? + "" + else + val.inspect + end + end + + sig do + params(pretty_kvs: T::Array[[Symbol, String]], multiline: T::Boolean, indent: String) + .returns(String) + end + private def join_props_with_pretty_values(pretty_kvs, multiline:, indent: ' ') + pairs = pretty_kvs + .sort_by {|k, _v| k.to_s} + .map {|k, v| "#{k}=#{v}"} + + if multiline + indent + pairs.join("\n#{indent}") + else + pairs.join(', ') + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb new file mode 100644 index 0000000000..b86f506f9a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb @@ -0,0 +1,170 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + class ApplyDefault + extend T::Sig + extend T::Helpers + abstract! + + # checked(:never) - O(object construction x prop count) + 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)} + 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)} + def default; end + + # checked(:never) - O(object construction x prop count) + 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)} + def self.for(cls, rules) + accessor_key = rules.fetch(:accessor_key) + setter = rules.fetch(:setter_proc) + + if rules.key?(:factory) + ApplyDefaultFactory.new(cls, rules.fetch(:factory), accessor_key, setter) + elsif rules.key?(:default) + default = rules.fetch(:default) + case default + when *NO_CLONE_TYPES + return ApplyPrimitiveDefault.new(default, accessor_key, setter) + when String + if default.frozen? + return ApplyPrimitiveDefault.new(default, accessor_key, setter) + end + when Array + if default.empty? && default.class == Array + return ApplyEmptyArrayDefault.new(accessor_key, setter) + end + when Hash + if default.empty? && default.default.nil? && T.unsafe(default).default_proc.nil? && default.class == Hash + return ApplyEmptyHashDefault.new(accessor_key, setter) + end + end + + ApplyComplexDefault.new(default, accessor_key, setter) + else + nil + end + end + end + + class ApplyFixedDefault < ApplyDefault + abstract! + + # checked(:never) - We do this with `T.let` instead + 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. + # + # :( + # + # setter_proc.call(default) + @default = T.let(default, BasicObject) + super(accessor_key, setter_proc) + end + + # checked(:never) - O(object construction x prop count) + 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 + end + + class ApplyPrimitiveDefault < ApplyFixedDefault + # checked(:never) - O(object construction x prop count) + 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)} + def default + T::Props::Utils.deep_clone_object(@default) + end + end + + # Special case since it's so common, and a literal `[]` is meaningfully + # faster than falling back to ApplyComplexDefault or even calling + # `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)} + 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)} + def default + [] + end + end + + # Special case since it's so common, and a literal `{}` is meaningfully + # faster than falling back to ApplyComplexDefault or even calling + # `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)} + 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)} + def default + {} + end + end + + class ApplyDefaultFactory < ApplyDefault + # checked(:never) - We do this with `T.let` instead + sig do + params( + cls: Module, + factory: T.any(Proc, Method), + accessor_key: Symbol, + setter_proc: SetterFactory::SetterProc, + ) + .void + .checked(:never) + end + def initialize(cls, factory, accessor_key, setter_proc) + @class = T.let(cls, Module) + @factory = T.let(factory, T.any(Proc, Method)) + super(accessor_key, setter_proc) + end + + # checked(:never) - O(object construction x prop count) + 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 + instance.instance_exec(default, &@setter_proc) + end + + # checked(:never) - O(object construction x prop count) + sig {override.returns(T.untyped).checked(:never)} + def default + @class.class_exec(&@factory) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb new file mode 100644 index 0000000000..2393e1a284 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + + # Generates a specialized `deserialize` implementation for a subclass of + # T::Props::Serializable. + # + # The basic idea is that we analyze the props and for each prop, generate + # the simplest possible logic as a block of Ruby source, so that we don't + # pay the cost of supporting types like T:::Hash[CustomType, SubstructType] + # when deserializing a simple Integer. Then we join those together, + # with a little shared logic to be able to detect when we get input keys + # that don't match any prop. + module DeserializerGenerator + extend T::Sig + + # Generate a method that takes a T::Hash[String, T.untyped] representing + # serialized props, sets instance variables for each prop found in the + # input, and returns the count of we props set (which we can use to check + # for unexpected input keys with minimal effect on the fast path). + sig do + params( + props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]], + defaults: T::Hash[Symbol, T::Props::Private::ApplyDefault], + ) + .returns(String) + .checked(:never) + end + def self.generate(props, defaults) + 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 + # error message, but we double check here to prevent a refactoring + # from introducing a security vulnerability. + raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s) + + hash_key = rules.fetch(:serialized_form) + raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key) + + ivar_name = rules.fetch(:accessor_key).to_s + raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1]) + + transformation = SerdeTransform.generate( + T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)), + SerdeTransform::Mode::DESERIALIZE, + 'val' + ) + transformed_val = if transformation + # Rescuing exactly NoMethodError is intended as a temporary hack + # to preserve the semantics from before codegen. More generally + # we are inconsistent about typechecking on deser and need to decide + # our strategy here. + <<~RUBY + begin + #{transformation} + rescue NoMethodError => e + raise_deserialization_error( + #{prop.inspect}, + val, + e, + ) + val + end + RUBY + else + 'val' + end + + nil_handler = generate_nil_handler( + prop: prop, + serialized_form: hash_key, + default: defaults[prop], + nilable_type: T::Props::Utils.optional_prop?(rules), + raise_on_nil_write: !!rules[:raise_on_nil_write], + ) + + <<~RUBY + val = hash[#{hash_key.inspect}] + #{ivar_name} = if val.nil? + found -= 1 unless hash.key?(#{hash_key.inspect}) + #{nil_handler} + else + #{transformed_val} + end + RUBY + end + + <<~RUBY + def __t_props_generated_deserialize(hash) + found = #{stored_props.size} + #{parts.join("\n\n")} + found + end + RUBY + end + + # This is very similar to what we do in ApplyDefault, but has a few + # key differences that mean we don't just re-use the code: + # + # 1. Where the logic in construction is that we generate a default + # if & only if the prop key isn't present in the input, here we'll + # generate a default even to override an explicit nil, but only + # if the prop is actually required. + # 2. Since we're generating raw Ruby source, we can remove a layer + # of indirection for marginally better performance; this seems worth + # it for the common cases of literals and empty arrays/hashes. + # 3. We need to care about the distinction between `raise_on_nil_write` + # and actually non-nilable, where new-instance construction doesn't. + # + # So we fall back to ApplyDefault only when one of the cases just + # mentioned doesn't apply. + sig do + params( + prop: Symbol, + serialized_form: String, + default: T.nilable(ApplyDefault), + nilable_type: T::Boolean, + raise_on_nil_write: T::Boolean, + ) + .returns(String) + .checked(:never) + end + private_class_method def self.generate_nil_handler( + prop:, + serialized_form:, + default:, + nilable_type:, + raise_on_nil_write: + ) + if !nilable_type + case default + when NilClass + "self.class.decorator.raise_nil_deserialize_error(#{serialized_form.inspect})" + when ApplyPrimitiveDefault + literal = default.default + case literal + when String, Integer, Symbol, Float, TrueClass, FalseClass, NilClass + literal.inspect + else + "self.class.decorator.props_with_defaults.fetch(#{prop.inspect}).default" + end + when ApplyEmptyArrayDefault + '[]' + when ApplyEmptyHashDefault + '{}' + else + "self.class.decorator.props_with_defaults.fetch(#{prop.inspect}).default" + end + elsif raise_on_nil_write + "required_prop_missing_from_deserialize(#{prop.inspect})" + else + 'nil' + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb new file mode 100644 index 0000000000..2ccd574118 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true +# typed: false + +module T::Props + module Private + module Parse + def parse(source) + @current_ruby ||= require_parser(:CurrentRuby) + @current_ruby.parse(source) + end + + def s(type, *children) + @node ||= require_parser(:AST, :Node) + @node.new(type, children) + end + + private def require_parser(*constants) + # This is an optional dependency for sorbet-runtime in general, + # but is required here + require 'parser/current' + + # Hack to work around the static checker thinking the constant is + # undefined + cls = Kernel.const_get(:Parser, true) + while (const = constants.shift) + cls = cls.const_get(const, false) + end + cls + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb new file mode 100644 index 0000000000..e0b37a376d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb @@ -0,0 +1,186 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + module SerdeTransform + extend T::Sig + + class Serialize; end + private_constant :Serialize + class Deserialize; end + private_constant :Deserialize + ModeType = T.type_alias {T.any(Serialize, Deserialize)} + private_constant :ModeType + + module Mode + SERIALIZE = T.let(Serialize.new.freeze, Serialize) + DESERIALIZE = T.let(Deserialize.new.freeze, Deserialize) + end + + NO_TRANSFORM_TYPES = T.let( + [TrueClass, FalseClass, NilClass, Symbol, String].freeze, + T::Array[Module], + ) + private_constant :NO_TRANSFORM_TYPES + + sig do + params( + type: T::Types::Base, + mode: ModeType, + varname: String, + ) + .returns(T.nilable(String)) + .checked(:never) + end + def self.generate(type, mode, varname) + case type + when T::Types::TypedArray + inner = generate(type.type, mode, 'v') + if inner.nil? + "#{varname}.dup" + else + "#{varname}.map {|v| #{inner}}" + end + when T::Types::TypedSet + inner = generate(type.type, mode, 'v') + if inner.nil? + "#{varname}.dup" + else + "Set.new(#{varname}) {|v| #{inner}}" + end + when T::Types::TypedHash + keys = generate(type.keys, mode, 'k') + values = generate(type.values, mode, 'v') + if keys && values + "#{varname}.each_with_object({}) {|(k,v),h| h[#{keys}] = #{values}}" + elsif keys + "#{varname}.transform_keys {|k| #{keys}}" + elsif values + "#{varname}.transform_values {|v| #{values}}" + else + "#{varname}.dup" + end + when T::Types::Simple + raw = type.raw_type + if NO_TRANSFORM_TYPES.any? {|cls| raw <= cls} + nil + elsif raw <= Float + case mode + when Deserialize then "#{varname}.to_f" + when Serialize then nil + else T.absurd(mode) + end + elsif raw <= Numeric + nil + elsif raw < T::Props::Serializable + handle_serializable_subtype(varname, raw, mode) + elsif raw.singleton_class < T::Props::CustomType + handle_custom_type(varname, T.unsafe(raw), mode) + elsif T::Configuration.scalar_types.include?(raw.name) + # It's a bit of a hack that this is separate from NO_TRANSFORM_TYPES + # and doesn't check inheritance (like `T::Props::CustomType.scalar_type?` + # does), but it covers the main use case (pay-server's custom `Boolean` + # module) without either requiring `T::Configuration.scalar_types` to + # accept modules instead of strings (which produces load-order issues + # and subtle behavior changes) or eating the performance cost of doing + # an inheritance check by manually crawling a class hierarchy and doing + # string comparisons. + nil + else + "T::Props::Utils.deep_clone_object(#{varname})" + end + when T::Types::Union + non_nil_type = T::Utils.unwrap_nilable(type) + if non_nil_type + inner = generate(non_nil_type, mode, varname) + if inner.nil? + nil + else + "#{varname}.nil? ? nil : #{inner}" + end + elsif type.types.all? {|t| generate(t, mode, varname).nil?} + # Handle, e.g., T::Boolean + nil + else + # We currently deep_clone_object if the type was T.any(Integer, Float). + # When we get better support for union types (maybe this specific + # union type, because it would be a replacement for + # Chalk::ODM::DeprecatedNumemric), we could opt to special case + # this union to have no specific serde transform (the only reason + # why Float has a special case is because round tripping through + # JSON might normalize Floats to Integers) + "T::Props::Utils.deep_clone_object(#{varname})" + end + when T::Types::Intersection + dynamic_fallback = "T::Props::Utils.deep_clone_object(#{varname})" + + # Transformations for any members of the intersection type where we + # know what we need to do and did not have to fall back to the + # dynamic deep clone method. + # + # 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} + .uniq + + if inner_known.size != 1 + # If there were no cases where we could tell what we need to do, + # e.g. if this is `T.all(SomethingWeird, WhoKnows)`, just use the + # dynamic fallback. + # + # If there were multiple cases and they weren't consistent, e.g. + # if this is `T.all(String, T::Array[Integer])`, the type is probably + # bogus/uninhabited, but use the dynamic fallback because we still + # don't have a better option, and this isn't the place to raise that + # error. + dynamic_fallback + else + # This is probably something like `T.all(String, SomeMarker)` or + # `T.all(SomeEnum, T.deprecated_enum(SomeEnum::FOO))` and we should + # treat it like String or SomeEnum even if we don't know what to do + # with the rest of the type. + inner_known.first + end + when T::Types::Enum + generate(T::Utils.lift_enum(type), mode, varname) + else + "T::Props::Utils.deep_clone_object(#{varname})" + end + end + + 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 + "#{varname}.serialize(strict)" + when Deserialize + type_name = T.must(module_name(type)) + "#{type_name}.from_hash(#{varname})" + else + T.absurd(mode) + end + end + + 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 + "T::Props::CustomType.checked_serialize(#{varname})" + when Deserialize + type_name = T.must(module_name(type)) + "#{type_name}.deserialize(#{varname})" + else + T.absurd(mode) + end + end + + 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 + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb new file mode 100644 index 0000000000..0d49a46e0f --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + + # Generates a specialized `serialize` implementation for a subclass of + # T::Props::Serializable. + # + # The basic idea is that we analyze the props and for each prop, generate + # the simplest possible logic as a block of Ruby source, so that we don't + # pay the cost of supporting types like T:::Hash[CustomType, SubstructType] + # when serializing a simple Integer. Then we join those together, + # with a little shared logic to be able to detect when we get input keys + # that don't match any prop. + module SerializerGenerator + extend T::Sig + + sig do + params( + props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]], + ) + .returns(String) + .checked(:never) + end + def self.generate(props) + 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 + # error message, but we double check here to prevent a refactoring + # from introducing a security vulnerability. + raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s) + + hash_key = rules.fetch(:serialized_form) + raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key) + + ivar_name = rules.fetch(:accessor_key).to_s + raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1]) + + transformed_val = SerdeTransform.generate( + T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)), + SerdeTransform::Mode::SERIALIZE, + ivar_name + ) || ivar_name + + nil_asserter = + if rules[:fully_optional] + '' + else + "required_prop_missing_from_serialize(#{prop.inspect}) if strict" + end + + # Don't serialize values that are nil to save space (both the + # nil value itself and the field name in the serialized BSON + # document) + <<~RUBY + if #{ivar_name}.nil? + #{nil_asserter} + else + h[#{hash_key.inspect}] = #{transformed_val} + end + RUBY + end + + <<~RUBY + def __t_props_generated_serialize(strict) + h = {} + #{parts.join("\n\n")} + h + end + RUBY + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb new file mode 100644 index 0000000000..00c76ed1e7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb @@ -0,0 +1,197 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + module SetterFactory + extend T::Sig + + SetterProc = 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( + klass: T.all(Module, T::Props::ClassMethods), + prop: Symbol, + rules: T::Hash[Symbol, T.untyped] + ) + .returns(SetterProc) + .checked(:never) + end + def self.build_setter_proc(klass, prop, rules) + # Our nil check works differently than a simple T.nilable for various + # reasons (including the `raise_on_nil_write` setting and the existence + # of defaults & factories), so unwrap any T.nilable and do a check + # manually. + non_nil_type = T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)) + accessor_key = rules.fetch(:accessor_key) + validate = rules[:setter_validate] + + # It seems like a bug that this affects the behavior of setters, but + # some existing code relies on this behavior + has_explicit_nil_default = rules.key?(:default) && rules.fetch(:default).nil? + + # Use separate methods in order to ensure that we only close over necessary + # variables + if !T::Props::Utils.need_nil_write_check?(rules) || has_explicit_nil_default + if validate.nil? && non_nil_type.is_a?(T::Types::Simple) + simple_nilable_proc(prop, accessor_key, non_nil_type.raw_type, klass) + else + nilable_proc(prop, accessor_key, non_nil_type, klass, validate) + end + else + if validate.nil? && non_nil_type.is_a?(T::Types::Simple) + simple_non_nil_proc(prop, accessor_key, non_nil_type.raw_type, klass) + else + non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) + end + end + end + + sig do + params( + prop: Symbol, + accessor_key: Symbol, + non_nil_type: Module, + klass: T.all(Module, T::Props::ClassMethods), + ) + .returns(SetterProc) + end + private_class_method def self.simple_non_nil_proc(prop, accessor_key, non_nil_type, klass) + proc do |val| + unless val.is_a?(non_nil_type) + T::Props::Private::SetterFactory.raise_pretty_error( + klass, + prop, + T::Utils.coerce(non_nil_type), + val, + ) + end + instance_variable_set(accessor_key, val) + end + end + + sig do + params( + prop: Symbol, + accessor_key: Symbol, + non_nil_type: T::Types::Base, + klass: T.all(Module, T::Props::ClassMethods), + validate: T.nilable(ValidateProc) + ) + .returns(SetterProc) + end + private_class_method def self.non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) + proc do |val| + # this use of recursively_valid? is intentional: unlike for + # methods, we want to make sure data at the 'edge' + # (e.g. models that go into databases or structs serialized + # from disk) are correct, so we use more thorough runtime + # checks there + if non_nil_type.recursively_valid?(val) + validate&.call(prop, val) + else + T::Props::Private::SetterFactory.raise_pretty_error( + klass, + prop, + non_nil_type, + val, + ) + end + instance_variable_set(accessor_key, val) + end + end + + sig do + params( + prop: Symbol, + accessor_key: Symbol, + non_nil_type: Module, + klass: T.all(Module, T::Props::ClassMethods), + ) + .returns(SetterProc) + end + private_class_method def self.simple_nilable_proc(prop, accessor_key, non_nil_type, klass) + proc do |val| + if val.nil? + instance_variable_set(accessor_key, nil) + elsif val.is_a?(non_nil_type) + instance_variable_set(accessor_key, val) + else + T::Props::Private::SetterFactory.raise_pretty_error( + klass, + prop, + T::Utils.coerce(non_nil_type), + val, + ) + instance_variable_set(accessor_key, val) + end + end + end + + sig do + params( + prop: Symbol, + accessor_key: Symbol, + non_nil_type: T::Types::Base, + klass: T.all(Module, T::Props::ClassMethods), + validate: T.nilable(ValidateProc), + ) + .returns(SetterProc) + end + private_class_method def self.nilable_proc(prop, accessor_key, non_nil_type, klass, validate) + proc do |val| + if val.nil? + instance_variable_set(accessor_key, nil) + # this use of recursively_valid? is intentional: unlike for + # methods, we want to make sure data at the 'edge' + # (e.g. models that go into databases or structs serialized + # from disk) are correct, so we use more thorough runtime + # checks there + elsif non_nil_type.recursively_valid?(val) + validate&.call(prop, val) + instance_variable_set(accessor_key, val) + else + T::Props::Private::SetterFactory.raise_pretty_error( + klass, + prop, + non_nil_type, + val, + ) + instance_variable_set(accessor_key, val) + end + end + end + + sig do + params( + klass: T.all(Module, T::Props::ClassMethods), + prop: Symbol, + type: T.any(T::Types::Base, Module), + val: T.untyped, + ) + .void + end + def self.raise_pretty_error(klass, prop, type, val) + 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')} + if caller_loc + pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" + end + + T::Configuration.call_validation_error_handler( + nil, + message: base_message, + pretty_message: pretty_message, + kind: 'Parameter', + name: prop, + type: type, + value: val, + location: caller_loc, + ) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb new file mode 100644 index 0000000000..2e2ea1b749 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb @@ -0,0 +1,374 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::Serializable + include T::Props::Plugin + # Required because we have special handling for `optional: false` + include T::Props::Optional + # Required because we have special handling for extra_props + include T::Props::PrettyPrintable + + # Serializes this object to a hash, suitable for conversion to + # JSON/BSON. + # + # @param strict [T::Boolean] (true) If false, do not raise an + # exception if this object has mandatory props with missing + # values. + # @return [Hash] A serialization of this object. + def serialize(strict=true) + begin + h = __t_props_generated_serialize(strict) + rescue => e + msg = self.class.decorator.message_with_generated_source_context( + e, + :__t_props_generated_serialize, + :generate_serialize_source + ) + if msg + begin + raise e.class.new(msg) + rescue ArgumentError + raise TypeError.new(msg) + end + else + raise + end + end + + h.merge!(@_extra_props) if defined?(@_extra_props) + h + end + + private def __t_props_generated_serialize(strict) + # No-op; will be overridden if there are any props. + # + # To see the definition for class `Foo`, run `Foo.decorator.send(:generate_serialize_source)` + {} + end + + # Populates the property values on this object with the values + # from a hash. In general, prefer to use {.from_hash} to construct + # a new instance, instead of loading into an existing instance. + # + # @param hash [Hash] The hash to take property + # values from. + # @param strict [T::Boolean] (false) If true, raise an exception if + # the hash contains keys that do not correspond to any known + # props on this instance. + # @return [void] + def deserialize(hash, strict=false) + begin + hash_keys_matching_props = __t_props_generated_deserialize(hash) + rescue => e + msg = self.class.decorator.message_with_generated_source_context( + e, + :__t_props_generated_deserialize, + :generate_deserialize_source + ) + if msg + begin + raise e.class.new(msg) + rescue ArgumentError + raise TypeError.new(msg) + end + else + raise + end + end + + 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` could still be empty here if the input matches a `dont_store` prop; + # historically, we just ignore those + if !extra.empty? + if strict + raise "Unknown properties for #{self.class.name}: #{extra.keys.inspect}" + else + @_extra_props = extra + end + end + end + end + + private def __t_props_generated_deserialize(hash) + # No-op; will be overridden if there are any props. + # + # To see the definition for class `Foo`, run `Foo.decorator.send(:generate_deserialize_source)` + 0 + end + + # with() will clone the old object to the new object and merge the specified props to the new object. + def with(changed_props) + with_existing_hash(changed_props, existing_hash: self.serialize) + end + + private def recursive_stringify_keys(obj) + if obj.is_a?(Hash) + new_obj = obj.class.new + obj.each do |k, v| + new_obj[k.to_s] = recursive_stringify_keys(v) + end + elsif obj.is_a?(Array) + new_obj = obj.map {|v| recursive_stringify_keys(v)} + else + new_obj = obj + end + new_obj + end + + private def with_existing_hash(changed_props, existing_hash:) + serialized = existing_hash + new_val = self.class.from_hash(serialized.merge(recursive_stringify_keys(changed_props))) + old_extra = self.instance_variable_get(:@_extra_props) if self.instance_variable_defined?(:@_extra_props) + new_extra = new_val.instance_variable_get(:@_extra_props) if new_val.instance_variable_defined?(:@_extra_props) + if old_extra != new_extra + difference = + if old_extra + new_extra.reject {|k, v| old_extra[k] == v} + else + new_extra + end + raise ArgumentError.new("Unexpected arguments: input(#{changed_props}), unexpected(#{difference})") + end + new_val + end + + # Asserts if this property is missing during strict serialize + private def required_prop_missing_from_serialize(prop) + if defined?(@_required_props_missing_from_deserialize) && + @_required_props_missing_from_deserialize&.include?(prop) + # If the prop was already missing during deserialization, that means the application + # code already had to deal with a nil value, which means we wouldn't be accomplishing + # much by raising here (other than causing an unnecessary breakage). + T::Configuration.log_info_handler( + "chalk-odm: missing required property in serialize", + prop: prop, class: self.class.name, id: self.class.decorator.get_id(self) + ) + else + raise TypeError.new("#{self.class.name}.#{prop} not set for non-optional prop") + end + end + + # Marks this property as missing during deserialize + private def required_prop_missing_from_deserialize(prop) + @_required_props_missing_from_deserialize ||= Set[] + @_required_props_missing_from_deserialize << prop + nil + end + + private def raise_deserialization_error(prop_name, value, orig_error) + T::Configuration.soft_assert_handler( + 'Deserialization error (probably unexpected stored type)', + storytime: { + klass: self.class, + prop: prop_name, + value: value, + error: orig_error.message, + notify: 'djudd' + } + ) + end +end + +############################################## + +# NB: This must stay in the same file where T::Props::Serializable is defined due to +# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 +module T::Props::Serializable::DecoratorMethods + include T::Props::HasLazilySpecializedMethods::DecoratorMethods + + # Heads up! + # + # There are already too many ad-hoc options on the prop DSL. + # + # We have already done a lot of work to remove unnecessary and confusing + # options. If you're considering adding a new rule key, please come chat with + # the Sorbet team first, as we'd really like to learn more about how to best + # solve the problem you're encountering. + VALID_RULE_KEYS = {dont_store: true, name: true, raise_on_nil_write: true}.freeze + private_constant :VALID_RULE_KEYS + + def valid_rule_key?(key) + super || VALID_RULE_KEYS[key] + end + + def required_props + @class.props.select {|_, v| T::Props::Utils.required_prop?(v)}.keys + end + + def prop_dont_store?(prop) + prop_rules(prop)[:dont_store] + end + def prop_by_serialized_forms + @class.prop_by_serialized_forms + end + + def from_hash(hash, strict=false) + raise ArgumentError.new("#{hash.inspect} provided to from_hash") if !(hash && hash.is_a?(Hash)) + + i = @class.allocate + i.deserialize(hash, strict) + + i + end + + def prop_serialized_form(prop) + prop_rules(prop)[:serialized_form] + end + + def serialized_form_prop(serialized_form) + prop_by_serialized_forms[serialized_form.to_s] || raise("No such serialized form: #{serialized_form.inspect}") + end + + def add_prop_definition(prop, rules) + rules[:serialized_form] = rules.fetch(:name, prop.to_s) + res = super + prop_by_serialized_forms[rules[: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} + else + 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 + + private def generate_serialize_source + T::Props::Private::SerializerGenerator.generate(props) + end + + private def generate_deserialize_source + T::Props::Private::DeserializerGenerator.generate( + props, + props_with_defaults || {}, + ) + end + + private def generate_serialize2 + T::Props::Private::SerializerGenerator.generate2(decorated_class, props) + end + + private def generate_deserialize2 + T::Props::Private::DeserializerGenerator.generate2( + decorated_class, + props, + props_with_defaults || {}, + ) + end + + def message_with_generated_source_context(error, generated_method, generate_source_method) + line_label = error.backtrace.find {|l| l.end_with?("in `#{generated_method}'")} + return unless line_label + + line_num = line_label.split(':')[1]&.to_i + return unless line_num + + source_lines = self.send(generate_source_method).split("\n") + previous_blank = source_lines[0...line_num].rindex(&:empty?) || 0 + next_blank = line_num + (source_lines[line_num..-1]&.find_index(&:empty?) || 0) + context = " #{source_lines[(previous_blank + 1)...next_blank].join("\n ")}" + <<~MSG + Error in #{decorated_class.name}##{generated_method}: #{error.message} + at line #{line_num - previous_blank - 1} in: + #{context} + MSG + end + + def raise_nil_deserialize_error(hkey) + msg = "Tried to deserialize a required prop from a nil value. It's "\ + "possible that a nil value exists in the database, so you should "\ + "provide a `default: or factory:` for this prop (see go/optional "\ + "for more details). If this is already the case, you probably "\ + "omitted a required prop from the `fields:` option when doing a "\ + "partial load." + storytime = {prop: hkey, klass: decorated_class.name} + + # Notify the model owner if it exists, and always notify the API owner. + begin + if T::Configuration.class_owner_finder && (owner = T::Configuration.class_owner_finder.call(decorated_class)) + T::Configuration.hard_assert_handler( + msg, + storytime: storytime, + project: owner + ) + end + ensure + T::Configuration.hard_assert_handler(msg, storytime: storytime) + end + end + + def prop_validate_definition!(name, cls, rules, type) + result = super + + if (rules_name = rules[:name]) + unless rules_name.is_a?(String) + raise ArgumentError.new("Invalid name in prop #{@class.name}.#{name}: #{rules_name.inspect}") + end + + validate_prop_name(rules_name) + end + + if !rules[:raise_on_nil_write].nil? && rules[:raise_on_nil_write] != true + raise ArgumentError.new("The value of `raise_on_nil_write` if specified must be `true` (given: #{rules[:raise_on_nil_write]}).") + end + + result + end + + def get_id(instance) + prop = prop_by_serialized_forms['_id'] + if prop + get(instance, prop) + else + nil + end + end + + EMPTY_EXTRA_PROPS = {}.freeze + private_constant :EMPTY_EXTRA_PROPS + + def extra_props(instance) + if instance.instance_variable_defined?(:@_extra_props) + instance.instance_variable_get(:@_extra_props) || EMPTY_EXTRA_PROPS + else + EMPTY_EXTRA_PROPS + end + end + + # overrides T::Props::PrettyPrintable + private def inspect_instance_components(instance, multiline:, indent:) + if (extra_props = extra_props(instance)) && !extra_props.empty? + pretty_kvs = extra_props.map {|k, v| [k.to_sym, v.inspect]} + extra = join_props_with_pretty_values(pretty_kvs, multiline: false) + super + ["@_extra_props=<#{extra}>"] + else + super + end + end +end + +############################################## + +# NB: This must stay in the same file where T::Props::Serializable is defined due to +# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 +module T::Props::Serializable::ClassMethods + def prop_by_serialized_forms + @prop_by_serialized_forms ||= {} + end + + # Allocate a new instance and call {#deserialize} to load a new + # object from a hash. + # @return [Serializable] + def from_hash(hash, strict=false) + self.decorator.from_hash(hash, strict) + end + + # Equivalent to {.from_hash} with `strict` set to true. + # @return [Serializable] + def from_hash!(hash) + self.decorator.from_hash(hash, true) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb new file mode 100644 index 0000000000..ae3557783d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::TypeValidation + include T::Props::Plugin + + BANNED_TYPES = [Object, BasicObject, Kernel].freeze + + class UnderspecifiedType < ArgumentError; end + + module DecoratorMethods + extend T::Sig + + sig {params(key: Symbol).returns(T::Boolean).checked(:never)} + def valid_rule_key?(key) + super || key == :DEPRECATED_underspecified_type + end + + sig do + params( + name: T.any(Symbol, String), + _cls: Module, + rules: T::Hash[Symbol, T.untyped], + type: T.any(T::Types::Base, Module) + ) + .void + end + def prop_validate_definition!(name, _cls, rules, type) + super + + if !rules[:DEPRECATED_underspecified_type] + validate_type(type, field_name: name) + elsif rules[:DEPRECATED_underspecified_type] && find_invalid_subtype(type).nil? + raise ArgumentError.new("DEPRECATED_underspecified_type set unnecessarily for #{@class.name}.#{name} - #{type} is a valid type") + end + end + + sig do + params( + type: T::Types::Base, + field_name: T.any(Symbol, String), + ) + .void + end + private def validate_type(type, field_name:) + if (invalid_subtype = find_invalid_subtype(type)) + raise UnderspecifiedType.new(type_error_message(invalid_subtype, field_name, type)) + end + end + + # Returns an invalid type, if any, found in the given top-level type. + # This might be the type itself, if it is e.g. "Object", or might be + # a subtype like the type of the values of a typed hash. + # + # 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)} + 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 + 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 + 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 + if invalid.length == type.types.length + invalid.first + else + nil + end + when T::Types::Enum, T::Types::ClassOf + nil + when T::Private::Types::TypeAlias + find_invalid_subtype(type.aliased_type) + when T::Types::Simple + # TODO Could we manage to define a whitelist, consisting of something + # like primitives, subdocs, DataInterfaces, and collections/enums/unions + # thereof? + if BANNED_TYPES.include?(type.raw_type) + type + else + nil + end + else + type + end + end + + sig do + params( + type: T::Types::Base, + field_name: T.any(Symbol, String), + orig_type: T::Types::Base, + ) + .returns(String) + end + private def type_error_message(type, field_name, orig_type) + msg_prefix = "#{@class.name}.#{field_name}: #{orig_type} is invalid in prop definition" + if type == orig_type + "#{msg_prefix}. Please choose a more specific type (T.untyped and ~equivalents like Object are banned)." + else + "#{msg_prefix}. Please choose a subtype more specific than #{type} (T.untyped and ~equivalents like Object are banned)." + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb new file mode 100644 index 0000000000..33d1abadce --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true +# typed: true + +module T::Props::Utils + # Deep copy an object. The object must consist of Ruby primitive + # types and Hashes and Arrays. + def self.deep_clone_object(what, freeze: false) + result = case what + when true + true + when false + false + when Symbol, NilClass, Numeric + what + when Array + what.map {|v| deep_clone_object(v, freeze: freeze)} + when Hash + h = what.class.new + what.each do |k, v| + k.freeze if freeze + h[k] = deep_clone_object(v, freeze: freeze) + end + h + when Regexp + what.dup + when T::Enum + what + else + what.clone + end + freeze ? result.freeze : result + end + + # The prop_rules indicate whether we should check for reading a nil value for the prop/field. + # This is mostly for the compatibility check that we allow existing documents carry some nil prop/field. + def self.need_nil_read_check?(prop_rules) + # . :on_load allows nil read, but we need to check for the read for future writes + prop_rules[:optional] == :on_load || prop_rules[:raise_on_nil_write] + end + + # The prop_rules indicate whether we should check for writing a nil value for the prop/field. + def self.need_nil_write_check?(prop_rules) + need_nil_read_check?(prop_rules) || T::Props::Utils.required_prop?(prop_rules) + end + + def self.required_prop?(prop_rules) + # Clients should never reference :_tnilable as the implementation can change. + !prop_rules[:_tnilable] + end + + def self.optional_prop?(prop_rules) + # Clients should never reference :_tnilable as the implementation can change. + !!prop_rules[:_tnilable] + end + + def self.merge_serialized_optional_rule(prop_rules) + {'_tnilable' => true}.merge(prop_rules.merge('_tnilable' => true)) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb new file mode 100644 index 0000000000..3ffe1be695 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::WeakConstructor + include T::Props::Optional + extend T::Sig + + # checked(:never) - O(runtime object construction) + sig {params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never)} + def initialize(hash={}) + decorator = self.class.decorator + + hash_keys_matching_props = decorator.construct_props_with_defaults(self, hash) + + decorator.construct_props_without_defaults(self, hash) + + if hash_keys_matching_props < hash.size + raise ArgumentError.new("#{self.class}: Unrecognized properties: #{(hash.keys - decorator.props.keys).join(', ')}") + end + end +end + +module T::Props::WeakConstructor::DecoratorMethods + extend T::Sig + + # Set values for all props that have no defaults. Ignore any not present. + # + # @return [Integer] A count of props that we successfully initialized (which + # 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)} + 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. + result = 0 + props_without_defaults&.each_pair do |p, setter_proc| + if hash.key?(p) + instance.instance_exec(hash[p], &setter_proc) + result += 1 + end + end + result + end + + # Set values for all props that have defaults. Use the default if and only if + # the prop key isn't in the input. + # + # @return [Integer] A count of props that we successfully initialized (which + # 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)} + 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. + result = 0 + props_with_defaults&.each_pair do |p, default_struct| + if hash.key?(p) + instance.instance_exec(hash[p], &default_struct.setter_proc) + result += 1 + else + default_struct.set_default(instance) + end + end + result + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb new file mode 100644 index 0000000000..3112adf861 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +# typed: strict + +# Used as a mixin to any class so that you can call `sig`. +# Docs at https://sorbet.org/docs/sigs +module T::Sig + module WithoutRuntime + # 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. + def self.sig(arg0=nil, &blk); end + + original_verbose = $VERBOSE + $VERBOSE = false + + # 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} + def self.sig(arg0=nil, &blk); end # rubocop:disable Lint/DuplicateMethods + + $VERBOSE = original_verbose + end + + # 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} + def sig(arg0=nil, &blk) + T::Private::Methods.declare_sig(self, Kernel.caller_locations(1, 1)&.first, arg0, &blk) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb new file mode 100644 index 0000000000..5f35d1f81f --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +# typed: true + +class T::InexactStruct + include T::Props + include T::Props::Serializable + include T::Props::Constructor +end + +class T::Struct < T::InexactStruct + def self.inherited(subclass) + super(subclass) + T::Private::ClassUtils.replace_method(subclass.singleton_class, :inherited) do |s| + super(s) + raise "#{self.name} is a subclass of T::Struct and cannot be subclassed" + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb new file mode 100644 index 0000000000..059956a68d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Modeling AttachedClass properly at runtime would require additional + # tracking, so at runtime we permit all values and rely on the static checker. + # As AttachedClass is modeled statically as a type member on every singleton + # class, this is consistent with the runtime behavior for all type members. + class AttachedClassType < Base + + def initialize(); end + + # overrides Base + def name + "T.attached_class" + end + + # overrides Base + def valid?(obj) + true + end + + # overrides Base + private def subtype_of_single?(other) + case other + when AttachedClassType + true + else + false + end + end + + module Private + INSTANCE = AttachedClassType.new.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb new file mode 100644 index 0000000000..cce89b178a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb @@ -0,0 +1,172 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class Base + def self.method_added(method_name) + super(method_name) + # What is now `subtype_of_single?` used to be named `subtype_of?`. Make sure people don't + # override the wrong thing. + # + # NB: Outside of T::Types, we would enforce this by using `sig` and not declaring the method + # as overridable, but doing so here would result in a dependency cycle. + if method_name == :subtype_of? && self != T::Types::Base + raise "`subtype_of?` should not be overridden. You probably want to override " \ + "`subtype_of_single?` instead." + end + end + + # this will be redefined in certain subclasses + def recursively_valid?(obj) + valid?(obj) + end + + def valid?(obj) + raise NotImplementedError + end + + # @return [T::Boolean] This method must be implemented to return whether the subclass is a subtype + # of `type`. This should only be called by `subtype_of?`, which guarantees that `type` will be + # a "single" type, by which we mean it won't be a Union or an Intersection (c.f. + # `isSubTypeSingle` in sorbet). + private def subtype_of_single?(type) + raise NotImplementedError + end + + # Equality is based on name, so be sure the name reflects all relevant state when implementing. + def name + raise NotImplementedError + end + + # Mirrors ruby_typer::core::Types::isSubType + # See https://git.corp.stripe.com/stripe-internal/ruby-typer/blob/9fc8ed998c04ac0b96592ae6bb3493b8a925c5c1/core/types/subtyping.cc#L912-L950 + # + # This method cannot be overridden (see `method_added` above). + # Subclasses only need to implement `subtype_of_single?`). + def subtype_of?(t2) + t1 = self + + if t2.is_a?(T::Private::Types::TypeAlias) + t2 = t2.aliased_type + end + + if t1.is_a?(T::Private::Types::TypeAlias) + return t1.aliased_type.subtype_of?(t2) + end + + # pairs to cover: 1 (_, _) + # 2 (_, And) + # 3 (_, Or) + # 4 (And, _) + # 5 (And, And) + # 6 (And, Or) + # 7 (Or, _) + # 8 (Or, And) + # 9 (Or, Or) + + # 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)} + 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)} + 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)} + end + 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)} + end + + # 1; Start with some special cases + if t1.is_a?(T::Private::Types::Void) + return t2.is_a?(T::Private::Types::Void) + end + + if t1.is_a?(T::Types::Untyped) || t2.is_a?(T::Types::Untyped) + return true + end + + # Rest of (1) + subtype_of_single?(t2) + end + + def to_s + name + end + + def describe_obj(obj) + # Would be redundant to print class and value in these common cases. + case obj + when nil, true, false + return "type #{obj.class}" + end + + # In rare cases, obj.inspect may fail, or be undefined, so rescue. + begin + # Default inspect behavior of, eg; `#` is ugly; just print the hash instead, which is more concise/readable. + if obj.method(:inspect).owner == Kernel + "type #{obj.class} with hash #{obj.hash}" + elsif T::Configuration.include_value_in_type_errors? + "type #{obj.class} with value #{T::Utils.string_truncate_middle(obj.inspect, 30, 30)}" + else + "type #{obj.class}" + end + rescue StandardError, SystemStackError + "type #{obj.class} with unprintable value" + end + end + + def error_message_for_obj(obj) + if valid?(obj) + nil + else + error_message(obj) + end + end + + def error_message_for_obj_recursive(obj) + if recursively_valid?(obj) + nil + else + error_message(obj) + end + end + + private def error_message(obj) + "Expected type #{self.name}, got #{describe_obj(obj)}" + end + + def validate!(obj) + err = error_message_for_obj(obj) + raise TypeError.new(err) if err + end + + ### Equality methods (necessary for deduping types with `uniq`) + + def hash + name.hash + end + + # Type equivalence, defined by serializing the type to a string (with + # `#name`) and comparing the resulting strings for equality. + def ==(other) + (T::Utils.resolve_alias(other).class == T::Utils.resolve_alias(self).class) && + other.name == self.name + end + + alias_method :eql?, :== + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb new file mode 100644 index 0000000000..d56f21d4c7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Validates that an object belongs to the specified class. + class ClassOf < Base + attr_reader :type + + def initialize(type) + @type = type + end + + # overrides Base + def name + "T.class_of(#{@type})" + end + + # overrides Base + def valid?(obj) + obj.is_a?(Module) && obj <= @type + end + + # overrides Base + def subtype_of_single?(other) + case other + when ClassOf + @type <= other.type + when Simple + @type.is_a?(other.raw_type) + else + false + end + end + + # overrides Base + def describe_obj(obj) + obj.inspect + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb new file mode 100644 index 0000000000..97ecfe0c0c --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # validates that the provided value is within a given set/enum + class Enum < Base + extend T::Sig + + attr_reader :values + + def initialize(values) + @values = values + end + + # overrides Base + def valid?(obj) + @values.member?(obj) + end + + # overrides Base + private def subtype_of_single?(other) + case other + when Enum + (other.values - @values).empty? + else + false + end + end + + # overrides Base + def name + "T.deprecated_enum([#{@values.map(&:inspect).join(', ')}])" + end + + # overrides Base + def describe_obj(obj) + obj.inspect + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb new file mode 100644 index 0000000000..3bed082bcc --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true +# https://jira.corp.stripe.com/browse/RUBYPLAT-1107 +# typed: false + +module T::Types + # Takes a list of types. Validates each item in an array using the type in the same position + # in the list. + class FixedArray < Base + attr_reader :types + + def initialize(types) + @types = types.map {|type| T::Utils.coerce(type)} + end + + # overrides Base + def name + "[#{@types.join(', ')}]" + end + + # overrides Base + def recursively_valid?(obj) + if obj.is_a?(Array) && obj.length == @types.length + i = 0 + while i < @types.length + if !@types[i].recursively_valid?(obj[i]) + return false + end + i += 1 + end + true + else + false + end + end + + # overrides Base + def valid?(obj) + if obj.is_a?(Array) && obj.length == @types.length + i = 0 + while i < @types.length + if !@types[i].valid?(obj[i]) + return false + end + i += 1 + end + true + else + false + end + end + + # overrides Base + private def subtype_of_single?(other) + case other + when FixedArray + # Properly speaking, covariance here is unsound since arrays + # can be mutated, but sorbet implements covariant tuples for + # ease of adoption. + @types.size == other.types.size && @types.zip(other.types).all? do |t1, t2| + t1.subtype_of?(t2) + end + else + false + end + end + + # This gives us better errors, e.g.: + # "Expected [String, Symbol], got [String, String]" + # instead of + # "Expected [String, Symbol], got Array". + # + # overrides Base + def describe_obj(obj) + if obj.is_a?(Array) + if obj.length == @types.length + item_classes = obj.map(&:class).join(', ') + "type [#{item_classes}]" + else + "array of size #{obj.length}" + end + else + super + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb new file mode 100644 index 0000000000..d8fddb3703 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Takes a hash of types. Validates each item in a hash using the type in the same position + # in the list. + class FixedHash < Base + attr_reader :types + + def initialize(types) + @types = types.transform_values {|v| T::Utils.coerce(v)} + end + + # overrides Base + def name + serialize_hash(@types) + end + + # 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]} + 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]} + true + end + + # overrides Base + private def subtype_of_single?(other) + case other + when FixedHash + # Using `subtype_of?` here instead of == would be unsound + @types == other.types + else + false + end + end + + # This gives us better errors, e.g.: + # `Expected {a: String}, got {a: TrueClass}` + # instead of + # `Expected {a: String}, got Hash`. + # + # overrides Base + def describe_obj(obj) + if obj.is_a?(Hash) + "type #{serialize_hash(obj.transform_values(&:class))}" + else + super + end + end + + private + + def serialize_hash(hash) + entries = hash.map do |(k, v)| + if Symbol === k && ":#{k}" == k.inspect + "#{k}: #{v}" + else + "#{k.inspect} => #{v}" + end + end + + "{#{entries.join(', ')}}" + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb new file mode 100644 index 0000000000..8e4b42f187 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Takes a list of types. Validates that an object matches all of the types. + class Intersection < Base + attr_reader :types + + def initialize(types) + @types = types.flat_map do |type| + type = T::Utils.resolve_alias(type) + if type.is_a?(Intersection) + # Simplify nested intersections (mostly so `name` returns a nicer value) + type.types + else + T::Utils.coerce(type) + end + end.uniq + end + + # overrides Base + def name + "T.all(#{@types.map(&:name).sort.join(', ')})" + end + + # overrides Base + def recursively_valid?(obj) + @types.all? {|type| type.recursively_valid?(obj)} + end + + # overrides Base + def valid?(obj) + @types.all? {|type| type.valid?(obj)} + end + + # overrides Base + private def subtype_of_single?(other) + raise "This should never be reached if you're going through `subtype_of?` (and you should be)" + end + + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb new file mode 100644 index 0000000000..c285797480 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # The bottom type + class NoReturn < Base + + def initialize; end + + # overrides Base + def name + "T.noreturn" + end + + # overrides Base + def valid?(obj) + false + end + + # overrides Base + private def subtype_of_single?(other) + true + end + + module Private + INSTANCE = NoReturn.new.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb new file mode 100644 index 0000000000..aece6a3a2f --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Defines the type of a proc (a ruby callable). At runtime, only + # validates that the value is a `::Proc`. + # + # At present, we only support fixed-arity procs with no optional or + # keyword arguments. + class Proc < Base + attr_reader :arg_types + attr_reader :returns + + def initialize(arg_types, returns) + @arg_types = {} + arg_types.each do |key, raw_type| + @arg_types[key] = T::Utils.coerce(raw_type) + end + @returns = T::Utils.coerce(returns) + end + + # overrides Base + def name + args = [] + @arg_types.each do |k, v| + args << "#{k}: #{v.name}" + end + "T.proc.params(#{args.join(', ')}).returns(#{returns})" + end + + # overrides Base + def valid?(obj) + obj.is_a?(::Proc) + end + + # overrides Base + private def subtype_of_single?(other) + case other + when self.class + if arg_types.size != other.arg_types.size + return false + end + arg_types.values.zip(other.arg_types.values).all? do |a, b| + b.subtype_of?(a) + end && returns.subtype_of?(other.returns) + else + false + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb new file mode 100644 index 0000000000..e431a3e0f9 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Modeling self-types properly at runtime would require additional tracking, + # so at runtime we permit all values and rely on the static checker. + class SelfType < Base + + def initialize(); end + + # overrides Base + def name + "T.self_type" + end + + # overrides Base + def valid?(obj) + true + end + + # overrides Base + private def subtype_of_single?(other) + case other + when SelfType + true + else + false + end + end + + module Private + INSTANCE = SelfType.new.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb new file mode 100644 index 0000000000..2789adbb67 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Validates that an object belongs to the specified class. + class Simple < Base + attr_reader :raw_type + + def initialize(raw_type) + @raw_type = raw_type + end + + # overrides Base + def name + # Memoize to mitigate pathological performance with anonymous modules (https://bugs.ruby-lang.org/issues/11119) + # + # `name` isn't normally a hot path for types, but it is used in initializing a T::Types::Union, + # and so in `T.nilable`, and so in runtime constructions like `x = T.let(nil, T.nilable(Integer))`. + @name ||= @raw_type.name.freeze + end + + # overrides Base + def valid?(obj) + obj.is_a?(@raw_type) + end + + # overrides Base + private def subtype_of_single?(other) + case other + when Simple + @raw_type <= other.raw_type + else + false + end + end + + # overrides Base + private def error_message(obj) + error_message = super(obj) + actual_name = obj.class.name + + return error_message unless name == actual_name + + <<~MSG.strip + #{error_message} + + The expected type and received object type have the same name but refer to different constants. + Expected type is #{name} with object id #{@raw_type.__id__}, but received type is #{actual_name} with object id #{obj.class.__id__}. + + There might be a constant reloading problem in your application. + MSG + end + + def to_nilable + @nilable ||= T::Types::Union.new([self, T::Utils::Nilable::NIL_TYPE]) + end + + module Private + module Pool + @cache = ObjectSpace::WeakMap.new + + def self.type_for_module(mod) + cached = @cache[mod] + return cached if cached + + type = if mod == ::Array + T::Array[T.untyped] + elsif mod == ::Hash + T::Hash[T.untyped, T.untyped] + elsif mod == ::Enumerable + T::Enumerable[T.untyped] + elsif mod == ::Enumerator + T::Enumerator[T.untyped] + elsif mod == ::Range + T::Range[T.untyped] + elsif !Object.autoload?(:Set) && Object.const_defined?(:Set) && mod == ::Set + T::Set[T.untyped] + else + Simple.new(mod) + end + + # Unfortunately, we still need to check if the module is frozen, + # since WeakMap adds a finalizer to the key that is added + # to the map, so that it can clear the map entry when the key is + # garbage collected. + # For a frozen object, though, adding a finalizer is not a valid + # operation, so this still raises if `mod` is frozen. + @cache[mod] = type unless mod.frozen? + type + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb new file mode 100644 index 0000000000..121368c7b6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Validates that an object is equal to another T::Enum singleton value. + class TEnum < Base + attr_reader :val + + def initialize(val) + @val = val + end + + # overrides Base + def name + # Strips the #<...> off, just leaving the ... + # Reasoning: the user will have written something like + # T.any(MyEnum::A, MyEnum::B) + # in the type, so we should print what they wrote in errors, not: + # T.any(#, #) + @val.inspect[2..-2] + end + + # overrides Base + def valid?(obj) + @val == obj + end + + # overrides Base + private def subtype_of_single?(other) + case other + when TEnum + @val == other.val + else + false + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb new file mode 100644 index 0000000000..fadd2a7eea --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true +# typed: strict + +module T::Types + class TypeMember < TypeVariable + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb new file mode 100644 index 0000000000..ea82a07cc3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypeParameter < Base + def initialize(name) + raise ArgumentError.new("not a symbol: #{name}") unless name.is_a?(Symbol) + @name = name + end + + def valid?(obj) + true + end + + def subtype_of_single?(type) + true + end + + def name + "T.type_parameter(:#{@name})" + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb new file mode 100644 index 0000000000..8c83de8949 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true +# typed: strict + +module T::Types + class TypeTemplate < TypeVariable + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb new file mode 100644 index 0000000000..187119167d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Since we do type erasure at runtime, this just validates the variance and + # provides some syntax for the static type checker + class TypeVariable < Base + attr_reader :variance + + VALID_VARIANCES = %i[in out invariant].freeze + + def initialize(variance) + case variance + when Hash then raise ArgumentError.new("Pass bounds using a block. Got: #{variance}") + when *VALID_VARIANCES then nil + else + raise TypeError.new("invalid variance #{variance}") + end + @variance = variance + end + + def valid?(obj) + true + end + + def subtype_of_single?(type) + true + end + + def name + Untyped.new.name + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb new file mode 100644 index 0000000000..0b5f3541a9 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedArray < TypedEnumerable + # overrides Base + def name + "T::Array[#{@type.name}]" + end + + def underlying_class + Array + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Array) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Array) + end + + def new(*args) + Array.new(*T.unsafe(args)) + end + + class Untyped < TypedArray + def initialize + super(T.untyped) + end + + def valid?(obj) + obj.is_a?(Array) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb new file mode 100644 index 0000000000..65c2631f0a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb @@ -0,0 +1,176 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Note: All subclasses of Enumerable should add themselves to the + # `case` statement below in `describe_obj` in order to get better + # error messages. + class TypedEnumerable < Base + attr_reader :type + + def initialize(type) + @type = T::Utils.coerce(type) + end + + def underlying_class + Enumerable + end + + # overrides Base + def name + "T::Enumerable[#{@type.name}]" + end + + # overrides Base + def valid?(obj) + obj.is_a?(Enumerable) + end + + # overrides Base + def recursively_valid?(obj) + return false unless obj.is_a?(Enumerable) + case obj + when Array + begin + it = 0 + while it < obj.count + return false unless @type.recursively_valid?(obj[it]) + it += 1 + end + true + end + when Hash + return false unless @type.is_a?(FixedArray) + types = @type.types + return false if types.count != 2 + key_type = types[0] + value_type = types[1] + obj.each_pair do |key, val| + # Some objects (I'm looking at you Rack::Utils::HeaderHash) don't + # iterate over a [key, value] array, so we can't juse use the @type.recursively_valid?(v) + return false if !key_type.recursively_valid?(key) || !value_type.recursively_valid?(val) + end + true + when Enumerator::Lazy + # Enumerators can be unbounded: see `[:foo, :bar].cycle` + true + when Enumerator + # Enumerators can be unbounded: see `[:foo, :bar].cycle` + true + when Range + # A nil beginning or a nil end does not provide any type information. That is, nil in a range represents + # boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range + # of unknown types (T::Range[T.untyped]). + # Similarly, `(nil...1)` is not a `T::Range[T.nilable(Integer)]`, it's a boundless range of Integer. + (obj.begin.nil? || @type.recursively_valid?(obj.begin)) && (obj.end.nil? || @type.recursively_valid?(obj.end)) + when Set + obj.each do |item| + return false unless @type.recursively_valid?(item) + end + + true + else + # We don't check the enumerable since it isn't guaranteed to be + # rewindable (e.g. STDIN) and it may be expensive to enumerate + # (e.g. an enumerator that makes an HTTP request)" + true + end + end + + # overrides Base + private def subtype_of_single?(other) + if other.class <= TypedEnumerable && + underlying_class <= other.underlying_class + # Enumerables are covariant because they are read only + # + # Properly speaking, many Enumerable subtypes (e.g. Set) + # should be invariant because they are mutable and support + # both reading and writing. However, Sorbet treats *all* + # Enumerable subclasses as covariant for ease of adoption. + @type.subtype_of?(other.type) + else + false + end + end + + # overrides Base + def describe_obj(obj) + return super unless obj.is_a?(Enumerable) + type_from_instance(obj).name + end + + private def type_from_instances(objs) + return objs.class unless objs.is_a?(Enumerable) + obtained_types = [] + begin + objs.each do |x| + obtained_types << type_from_instance(x) + end + rescue + return T.untyped # all we can do is go with the types we have so far + end + if obtained_types.count > 1 + # Multiple kinds of bad types showed up, we'll suggest a union + # type you might want. + Union.new(obtained_types) + elsif obtained_types.empty? + T.noreturn + else + # Everything was the same bad type, lets just show that + obtained_types.first + end + end + + private def type_from_instance(obj) + if [true, false].include?(obj) + return T::Boolean + elsif !obj.is_a?(Enumerable) + return obj.class + end + + case obj + when Array + T::Array[type_from_instances(obj)] + when Hash + inferred_key = type_from_instances(obj.keys) + inferred_val = type_from_instances(obj.values) + T::Hash[inferred_key, inferred_val] + when Range + # We can't get any information from `NilClass` in ranges (since nil is used to represent boundlessness). + typeable_objects = [obj.begin, obj.end].compact + if typeable_objects.empty? + T::Range[T.untyped] + else + T::Range[type_from_instances(typeable_objects)] + end + when Enumerator::Lazy + T::Enumerator::Lazy[type_from_instances(obj)] + when Enumerator + T::Enumerator[type_from_instances(obj)] + when Set + T::Set[type_from_instances(obj)] + when IO + # Short circuit for anything IO-like (File, etc.). In these cases, + # enumerating the object is a destructive operation and might hang. + obj.class + else + # This is a specialized enumerable type, just return the class. + if T::Configuration::AT_LEAST_RUBY_2_7 + Object.instance_method(:class).bind_call(obj) + else + Object.instance_method(:class).bind(obj).call + end + end + end + + class Untyped < TypedEnumerable + def initialize + super(T.untyped) + end + + def valid?(obj) + obj.is_a?(Enumerable) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb new file mode 100644 index 0000000000..e79341eb94 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedEnumerator < TypedEnumerable + attr_reader :type + + def underlying_class + Enumerator + end + + # overrides Base + def name + "T::Enumerator[#{@type.name}]" + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Enumerator) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Enumerator) + end + + def new(*args, &blk) + T.unsafe(Enumerator).new(*args, &blk) + end + + class Untyped < TypedEnumerator + def initialize + super(T.untyped) + end + + def valid?(obj) + obj.is_a?(Enumerator) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb new file mode 100644 index 0000000000..3569be398a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedEnumeratorLazy < TypedEnumerable + attr_reader :type + + def underlying_class + Enumerator::Lazy + end + + # overrides Base + def name + "T::Enumerator::Lazy[#{@type.name}]" + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Enumerator::Lazy) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Enumerator::Lazy) + end + + def new(*args, &blk) + T.unsafe(Enumerator::Lazy).new(*args, &blk) + end + + class Untyped < TypedEnumeratorLazy + def initialize + super(T.untyped) + end + + def valid?(obj) + obj.is_a?(Enumerator::Lazy) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb new file mode 100644 index 0000000000..f48e0c1595 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedHash < TypedEnumerable + # Technically we don't need these, but they are a nice api + attr_reader :keys, :values + + def underlying_class + Hash + end + + def initialize(keys:, values:) + @keys = T::Utils.coerce(keys) + @values = T::Utils.coerce(values) + @type = T::Utils.coerce([keys, values]) + end + + # overrides Base + def name + "T::Hash[#{@keys.name}, #{@values.name}]" + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Hash) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Hash) + end + + def new(*args, &blk) + Hash.new(*T.unsafe(args), &blk) + end + + class Untyped < TypedHash + def initialize + super(keys: T.untyped, values: T.untyped) + end + + def valid?(obj) + obj.is_a?(Hash) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb new file mode 100644 index 0000000000..50e2ef9d53 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedRange < TypedEnumerable + attr_reader :type + + def underlying_class + Hash + end + + # overrides Base + def name + "T::Range[#{@type.name}]" + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Range) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Range) + end + + def new(*args) + T.unsafe(Range).new(*args) + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb new file mode 100644 index 0000000000..8c1b2caee3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedSet < TypedEnumerable + attr_reader :type + + def underlying_class + Hash + end + + # overrides Base + def name + "T::Set[#{@type.name}]" + end + + # overrides Base + def recursively_valid?(obj) + # Re-implements non_forcing_is_a? + return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set + return false unless Object.const_defined?(:Set) # Set is not loaded yet + obj.is_a?(Set) && super + end + + # overrides Base + def valid?(obj) + # Re-implements non_forcing_is_a? + return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set + return false unless Object.const_defined?(:Set) # Set is not loaded yet + obj.is_a?(Set) + end + + def new(*args) + # Fine for this to blow up, because hopefully if they're trying to make a + # Set, they don't mind putting (or already have put) a `require 'set'` in + # their program directly. + Set.new(*T.unsafe(args)) + end + + class Untyped < TypedSet + def initialize + super(T.untyped) + end + + def valid?(obj) + # Re-implements non_forcing_is_a? + return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set + return false unless Object.const_defined?(:Set) # Set is not loaded yet + obj.is_a?(Set) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb new file mode 100644 index 0000000000..3729dc48de --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Takes a list of types. Validates that an object matches at least one of the types. + class Union < Base + attr_reader :types + + def initialize(types) + @types = types.flat_map do |type| + type = T::Utils.coerce(type) + if type.is_a?(Union) + # Simplify nested unions (mostly so `name` returns a nicer value) + type.types + else + type + end + end.uniq + end + + # overrides Base + def name + type_shortcuts(@types) + end + + private def type_shortcuts(types) + if types.size == 1 + return types[0].name + end + 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} + "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} + type_shortcuts([T::Private::Types::StringHolder.new("T::Boolean")] + remaining_types) + else + names = types.map(&:name).compact.sort + "T.any(#{names.join(', ')})" + end + end + + # overrides Base + def recursively_valid?(obj) + @types.any? {|type| type.recursively_valid?(obj)} + end + + # overrides Base + def valid?(obj) + @types.any? {|type| type.valid?(obj)} + end + + # overrides Base + private def subtype_of_single?(other) + raise "This should never be reached if you're going through `subtype_of?` (and you should be)" + end + + module Private + module Pool + EMPTY_ARRAY = [].freeze + private_constant :EMPTY_ARRAY + + # @param type_a [T::Types::Base] + # @param type_b [T::Types::Base] + # @param types [Array] optional array of additional T::Types::Base instances + def self.union_of_types(type_a, type_b, types=EMPTY_ARRAY) + if types.empty? + # We aren't guaranteed to detect a simple `T.nilable()` type here + # in cases where there are duplicate types, nested unions, etc. + # + # That's ok, because this is an optimization which isn't necessary for + # correctness. + if type_b == T::Utils::Nilable::NIL_TYPE && type_a.is_a?(T::Types::Simple) + type_a.to_nilable + elsif type_a == T::Utils::Nilable::NIL_TYPE && type_b.is_a?(T::Types::Simple) + type_b.to_nilable + else + Union.new([type_a, type_b]) + end + else + # This can't be a `T.nilable()` case unless there are duplicates, + # which is possible but unexpected. + Union.new([type_a, type_b] + types) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb new file mode 100644 index 0000000000..a06a633d42 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # A dynamic type, which permits whatever + class Untyped < Base + + def initialize; end + + # overrides Base + def name + "T.untyped" + end + + # overrides Base + def valid?(obj) + true + end + + # overrides Base + private def subtype_of_single?(other) + true + end + + module Private + INSTANCE = Untyped.new.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb new file mode 100644 index 0000000000..7897eaa38f --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb @@ -0,0 +1,209 @@ +# frozen_string_literal: true +# typed: true + +module T::Utils + # Used to convert from a type specification to a `T::Types::Base`. + def self.coerce(val) + if val.is_a?(T::Private::Types::TypeAlias) + val.aliased_type + elsif val.is_a?(T::Types::Base) + val + elsif val.is_a?(Module) + T::Types::Simple::Private::Pool.type_for_module(val) + elsif val.is_a?(::Array) + T::Types::FixedArray.new(val) + elsif val.is_a?(::Hash) + T::Types::FixedHash.new(val) + elsif val.is_a?(T::Private::Methods::DeclBuilder) + T::Private::Methods.finalize_proc(val.decl) + elsif val.is_a?(::T::Enum) + T::Types::TEnum.new(val) + elsif val.is_a?(::String) + raise "Invalid String literal for type constraint. Must be an #{T::Types::Base}, a " \ + "class/module, or an array. Got a String with value `#{val}`." + else + raise "Invalid value for type constraint. Must be an #{T::Types::Base}, a " \ + "class/module, or an array. Got a `#{val.class}`." + end + end + + # Dynamically confirm that `value` is recursively a valid value of + # type `type`, including recursively through collections. Note that + # in some cases this runtime check can be very expensive, especially + # with large collections of objects. + def self.check_type_recursive!(value, type) + T::Private::Casts.cast_recursive(value, type, cast_method: "T.check_type_recursive!") + end + + # Returns the set of all methods (public, protected, private) defined on a module or its + # ancestors, excluding Object and its ancestors. Overrides of methods from Object (and its + # ancestors) are included. + def self.methods_excluding_object(mod) + # We can't just do mod.instance_methods - Object.instance_methods, because that would leave out + # any methods from Object that are overridden in mod. + mod.ancestors.flat_map do |ancestor| + # equivalent to checking Object.ancestors.include?(ancestor) + next [] if Object <= ancestor + ancestor.instance_methods(false) + ancestor.private_instance_methods(false) + end.uniq + end + + # Returns the signature for the `UnboundMethod`, or nil if it's not sig'd + # + # @example T::Utils.signature_for_method(x.method(:foo)) + def self.signature_for_method(method) + T::Private::Methods.signature_for_method(method) + end + + # Returns the signature for the instance method on the supplied module, or nil if it's not found or not typed. + # + # @example T::Utils.signature_for_instance_method(MyClass, :my_method) + def self.signature_for_instance_method(mod, method_name) + T::Private::Methods.signature_for_method(mod.instance_method(method_name)) + end + + def self.wrap_method_with_call_validation_if_needed(mod, method_sig, original_method) + T::Private::Methods::CallValidation.wrap_method_if_needed(mod, method_sig, original_method) + end + + # Unwraps all the sigs. + def self.run_all_sig_blocks + T::Private::Methods.run_all_sig_blocks + end + + # Return the underlying type for a type alias. Otherwise returns type. + def self.resolve_alias(type) + case type + when T::Private::Types::TypeAlias + type.aliased_type + else + type + end + end + + # Give a type which is a subclass of T::Types::Base, determines if the type is a simple nilable type (union of NilClass and something else). + # If so, returns the T::Types::Base of the something else. Otherwise, returns nil. + def self.unwrap_nilable(type) + case type + when T::Types::Union + non_nil_types = type.types.reject {|t| t == Nilable::NIL_TYPE} + return nil if type.types.length == non_nil_types.length + case non_nil_types.length + when 0 then nil + when 1 then non_nil_types.first + else + T::Types::Union::Private::Pool.union_of_types(non_nil_types[0], non_nil_types[1], non_nil_types[2..-1]) + end + else + nil + end + end + + # Returns the arity of a method, unwrapping the sig if needed + def self.arity(method) + arity = method.arity + return arity if arity != -1 || method.is_a?(Proc) + sig = T::Private::Methods.signature_for_method(method) + sig ? sig.method.arity : arity + end + + # Elide the middle of a string as needed and replace it with an ellipsis. + # Keep the given number of characters at the start and end of the string. + # + # This method operates on string length, not byte length. + # + # If the string is shorter than the requested truncation length, return it + # without adding an ellipsis. This method may return a longer string than + # the original if the characters removed are shorter than the ellipsis. + # + # @param [String] str + # + # @param [Fixnum] start_len The length of string before the ellipsis + # @param [Fixnum] end_len The length of string after the ellipsis + # + # @param [String] ellipsis The string to add in place of the elided text + # + # @return [String] + # + def self.string_truncate_middle(str, start_len, end_len, ellipsis='...') + return unless str + + raise ArgumentError.new('must provide start_len') unless start_len + raise ArgumentError.new('must provide end_len') unless end_len + + raise ArgumentError.new('start_len must be >= 0') if start_len < 0 + raise ArgumentError.new('end_len must be >= 0') if end_len < 0 + + str = str.to_s + return str if str.length <= start_len + end_len + + start_part = str[0...start_len - ellipsis.length] + end_part = end_len == 0 ? '' : str[-end_len..-1] + + "#{start_part}#{ellipsis}#{end_part}" + end + + def self.lift_enum(enum) + unless enum.is_a?(T::Types::Enum) + raise ArgumentError.new("#{enum.inspect} is not a T.deprecated_enum") + end + + classes = enum.values.map(&:class).uniq + if classes.empty? + T.untyped + elsif classes.length > 1 + T::Types::Union.new(classes) + else + T::Types::Simple::Private::Pool.type_for_module(classes.first) + end + end + + module Nilable + # :is_union_type, T::Boolean: whether the type is an T::Types::Union type + # :non_nilable_type, Class: if it is an T.nilable type, the corresponding underlying type; otherwise, nil. + TypeInfo = Struct.new(:is_union_type, :non_nilable_type) + + NIL_TYPE = T::Utils.coerce(NilClass) + + def self.get_type_info(prop_type) + if prop_type.is_a?(T::Types::Union) + non_nilable_type = T::Utils.unwrap_nilable(prop_type) + if non_nilable_type&.is_a?(T::Types::Simple) + non_nilable_type = non_nilable_type.raw_type + end + TypeInfo.new(true, non_nilable_type) + else + TypeInfo.new(false, nil) + end + end + + # Get the underlying type inside prop_type: + # - if the type is A, the function returns A + # - if the type is T.nilable(A), the function returns A + def self.get_underlying_type(prop_type) + type_info = get_type_info(prop_type) + if type_info.is_union_type + type_info.non_nilable_type || prop_type + elsif prop_type.is_a?(T::Types::Simple) + prop_type.raw_type + else + prop_type + end + end + + # The difference between this function and the above function is that the Sorbet type, like T::Types::Simple + # is preserved. + def self.get_underlying_type_object(prop_type) + T::Utils.unwrap_nilable(prop_type) || prop_type + end + + def self.is_union_with_nilclass(prop_type) + case prop_type + when T::Types::Union + prop_type.types.include?(NIL_TYPE) + else + false + end + end + end +end From bc687c63587684b2cd2db1dd470c646e9f265931 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 15:47:15 +0200 Subject: [PATCH 017/111] Added check `resources_only` --- Library/Homebrew/dev-cmd/livecheck.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 6c55f7e8d3..de7a343b9d 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,7 +70,8 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - formula_with_resources = Formula.all.select { |formula| formula.resources.any? } + # formula_with_resources = Formula.all.select { |formula| formula.resources.any? } + formula_with_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } formula_with_resources elsif args.all? formulae = args.cask? ? [] : Formula.all @@ -114,12 +115,13 @@ module Homebrew json: args.json?, full_name: args.full_name?, handle_name_conflict: !args.formula? && !args.cask?, + resources_only: args.resources?, newer_only: args.newer_only?, quiet: args.quiet?, debug: args.debug?, verbose: args.verbose?, }.compact - Livecheck.run_checks(package_and_resource_to_check[1..3], **options) + Livecheck.run_checks(package_and_resource_to_check, **options) end end From f4a42d7d6668878cedf124124bd4d098bd874c13 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 15:47:40 +0200 Subject: [PATCH 018/111] Added method `resource_version` to check for resources --- Library/Homebrew/livecheck/livecheck.rb | 313 +++++++++++++++++++++--- 1 file changed, 279 insertions(+), 34 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 50f4229385..854666816d 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -159,19 +159,20 @@ module Homebrew # `formulae_and_casks_to_check` array and prints the results. sig { params( - formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask, Resource)], - full_name: T::Boolean, - handle_name_conflict: T::Boolean, - json: T::Boolean, - newer_only: T::Boolean, - debug: T::Boolean, - quiet: T::Boolean, - verbose: T::Boolean, + formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], + full_name: T::Boolean, + handle_name_conflict: T::Boolean, + resources_only: T::Boolean, + json: T::Boolean, + newer_only: T::Boolean, + debug: T::Boolean, + quiet: T::Boolean, + verbose: T::Boolean, ).void } def run_checks( formulae_and_casks_to_check, - full_name: false, handle_name_conflict: false, json: false, newer_only: false, + full_name: false, handle_name_conflict: false, resources_only: false, json: false, newer_only: false, debug: false, quiet: false, verbose: false ) load_other_tap_strategies(formulae_and_casks_to_check) @@ -253,6 +254,9 @@ module Homebrew formula&.head&.downloader&.shutup! + # Check resources if "--resources" flag was given + + # Use the `stable` version for comparison except for installed # head-only formulae. A formula with `stable` and `head` that's # installed using `--head` will still use the `stable` version for @@ -267,18 +271,33 @@ module Homebrew Version.new(formula_or_cask.version) end + p "Formula: #{formula_or_cask_name(formula_or_cask, full_name: use_full_name)}" + p "Current: #{current.to_s}" + current_str = current.to_s current = LivecheckVersion.create(formula_or_cask, current) latest = if formula&.head_only? formula.head.downloader.fetch_last_commit else - version_info = latest_version( - formula_or_cask, - referenced_formula_or_cask: referenced_formula_or_cask, - livecheck_references: livecheck_references, - json: json, full_name: use_full_name, verbose: verbose, debug: debug - ) + if resources_only + version_info = resource_version( + formula_or_cask, + referenced_formula: referenced_formula_or_cask, + livecheck_references: livecheck_references, + json: json, + full_name: use_full_name, + verbose: verbose, + debug: debug + ) + else + version_info = latest_version( + formula_or_cask, + referenced_formula_or_cask: referenced_formula_or_cask, + livecheck_references: livecheck_references, + json: json, full_name: use_full_name, verbose: verbose, debug: debug + ) + end version_info[:latest] if version_info.present? end @@ -368,13 +387,15 @@ module Homebrew puts JSON.pretty_generate(formulae_checked.compact) end - sig { params(formula_or_cask: T.any(Formula, Cask::Cask), full_name: T::Boolean).returns(String) } + sig { params(formula_or_cask: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) } def formula_or_cask_name(formula_or_cask, full_name: false) case formula_or_cask when Formula formula_name(formula_or_cask, full_name: full_name) when Cask::Cask cask_name(formula_or_cask, full_name: full_name) + when Resource + resource_name(formula_or_cask, full_name: full_name) else T.absurd(formula_or_cask) end @@ -394,6 +415,13 @@ module Homebrew full_name ? formula.full_name : formula.name end + # Returns the fully-qualified name of a resource if the `full_name` argument is + # provided; returns the name otherwise. + sig { params(resource: Resource, full_name: T::Boolean).returns(String) } + def resource_name(resource, full_name: false) + full_name ? resource.full_name : resource.name + end + sig { params( formula_or_cask: T.any(Formula, Cask::Cask), @@ -449,41 +477,48 @@ module Homebrew sig { params( livecheck_url: T.any(String, Symbol), - formula_or_cask: T.any(Formula, Cask::Cask), + package_or_resource: T.any(Formula, Cask::Cask, Resource), ).returns(T.nilable(String)) } - def livecheck_url_to_string(livecheck_url, formula_or_cask) + def livecheck_url_to_string(livecheck_url, package_or_resource) case livecheck_url when String livecheck_url when :url - formula_or_cask.url&.to_s if formula_or_cask.is_a?(Cask::Cask) + package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) when :head, :stable - formula_or_cask.send(livecheck_url)&.url if formula_or_cask.is_a?(Formula) + package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) || package_or_resource.is_a?(Resource) when :homepage - formula_or_cask.homepage + package_or_resource.homepage end end # Returns an Array containing the formula/cask URLs that can be used by livecheck. - sig { params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(T::Array[String]) } - def checkable_urls(formula_or_cask) + sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource)).returns(T::Array[String]) } + def checkable_urls(package_or_resource) urls = [] - case formula_or_cask - when Formula - if formula_or_cask.stable - urls << formula_or_cask.stable.url - urls.concat(formula_or_cask.stable.mirrors) + case package_or_resource + when Resource + if package_or_resource.stable + urls << package_or_resource.stable.url + urls.concat(package_or_resource.stable.mirrors) end - urls << formula_or_cask.head.url if formula_or_cask.head - urls << formula_or_cask.homepage if formula_or_cask.homepage + urls << package_or_resource.head.url if package_or_resource.head + urls << package_or_resource.homepage if package_or_resource.homepage + when Formula + if package_or_resource.stable + urls << package_or_resource.stable.url + urls.concat(package_or_resource.stable.mirrors) + end + urls << package_or_resource.head.url if package_or_resource.head + urls << package_or_resource.homepage if package_or_resource.homepage when Cask::Cask - urls << formula_or_cask.appcast.to_s if formula_or_cask.appcast - urls << formula_or_cask.url.to_s if formula_or_cask.url - urls << formula_or_cask.homepage if formula_or_cask.homepage + urls << package_or_resource.appcast.to_s if package_or_resource.appcast + urls << package_or_resource.url.to_s if package_or_resource.url + urls << package_or_resource.homepage if package_or_resource.homepage else - T.absurd(formula_or_cask) + T.absurd(package_or_resource) end urls.compact.uniq @@ -561,6 +596,216 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end + #================================================================================== + + # Identifies the latest version of the resources and returns a Hash containing + # the version information. Returns nil if a latest version couldn't be found. + sig { + params( + formula_with_resources: T.any(Formula), + referenced_formula: T.nilable(T.any(Formula)), + livecheck_references: T::Array[T.any(Formula, Cask::Cask)], + json: T::Boolean, + full_name: T::Boolean, + verbose: T::Boolean, + debug: T::Boolean, + ).returns(T.nilable(Hash)) + } + def resource_version( + formula_with_resources, + referenced_formula: nil, + livecheck_references: [], + json: false, + full_name: false, + verbose: false, + debug: false + ) + formula_with_resources.resources.each_with_index do |resource, i| + has_livecheckable = resource.livecheckable? + + #@todo: for now, only check resources with livecheck block + if has_livecheckable + livecheck = resource.livecheck + # referenced_livecheck = referenced_formula_or_cask&.livecheck + livecheck_url = livecheck.url + livecheck_regex = livecheck.regex + livecheck_strategy = livecheck.strategy + livecheck_strategy_block = livecheck.strategy_block + + livecheck_url_string = livecheck_url_to_string( + livecheck_url, + resource, + ) + + urls = [livecheck_url_string] if livecheck_url_string + urls ||= checkable_urls(resource) + + end + + if debug + puts "Resource: #{resource_name(resource, full_name: full_name)}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + end + + end + + + + + + + # checked_urls = [] + # # rubocop:disable Metrics/BlockLength + # urls.each_with_index do |original_url, i| + # # Only preprocess the URL when it's appropriate + # url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + # original_url + # else + # preprocess_url(original_url) + # end + # next if checked_urls.include?(url) + + # strategies = Strategy.from_url( + # url, + # livecheck_strategy: livecheck_strategy, + # url_provided: livecheck_url.present?, + # regex_provided: livecheck_regex.present?, + # block_provided: livecheck_strategy_block.present?, + # ) + # strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + # strategy_name = livecheck_strategy_names[strategy] + + # if debug + # puts + # if livecheck_url.is_a?(Symbol) + # # This assumes the URL symbol will fit within the available space + # puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url + # else + # puts "URL: #{original_url}" + # end + # puts "URL (processed): #{url}" if url != original_url + # if strategies.present? && verbose + # puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" + # end + # puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + # puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + # end + + # if livecheck_strategy.present? + # if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + # odebug "#{strategy_name} strategy requires a URL" + # next + # elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + # odebug "#{strategy_name} strategy does not apply to this URL" + # next + # end + # end + + # next if strategy.blank? + + # homebrew_curl = case strategy_name + # when "PageMatch", "HeaderMatch" + # use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) + # end + # puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? + + # strategy_data = strategy.find_versions( + # url: url, + # regex: livecheck_regex, + # homebrew_curl: homebrew_curl, + # cask: cask, + # &livecheck_strategy_block + # ) + # match_version_map = strategy_data[:matches] + # regex = strategy_data[:regex] + # messages = strategy_data[:messages] + # checked_urls << url + + # if messages.is_a?(Array) && match_version_map.blank? + # puts messages unless json + # next if i + 1 < urls.length + + # return status_hash(formula_or_cask, "error", messages, full_name: full_name, verbose: verbose) + # end + + # if debug + # if strategy_data[:url].present? && strategy_data[:url] != url + # puts "URL (strategy): #{strategy_data[:url]}" + # end + # puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + # if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + # puts "Regex (strategy): #{strategy_data[:regex].inspect}" + # end + # puts "Cached?: Yes" if strategy_data[:cached] == true + # end + + # match_version_map.delete_if do |_match, version| + # next true if version.blank? + # next false if has_livecheckable + + # UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + # version.to_s.include?(rejection) + # end + # end + + # next if match_version_map.blank? + + # if debug + # puts + # puts "Matched Versions:" + + # if verbose + # match_version_map.each do |match, version| + # puts "#{match} => #{version.inspect}" + # end + # else + # puts match_version_map.values.join(", ") + # end + # end + + # version_info = { + # latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), + # } + + # if json && verbose + # version_info[:meta] = {} + + # if livecheck_references.present? + # version_info[:meta][:references] = livecheck_references.map do |ref_formula_or_cask| + # case ref_formula_or_cask + # when Formula + # { formula: formula_name(ref_formula_or_cask, full_name: full_name) } + # when Cask::Cask + # { cask: cask_name(ref_formula_or_cask, full_name: full_name) } + # end + # end + # end + + # version_info[:meta][:url] = {} + # version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + # version_info[:meta][:url][:original] = original_url + # version_info[:meta][:url][:processed] = url if url != original_url + # if strategy_data[:url].present? && strategy_data[:url] != url + # version_info[:meta][:url][:strategy] = strategy_data[:url] + # end + # version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + # version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + + # version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil + # version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? + # version_info[:meta][:regex] = regex.inspect if regex.present? + # version_info[:meta][:cached] = true if strategy_data[:cached] == true + # end + + # return version_info + # end + # rubocop:enable Metrics/BlockLength + + nil + end + + #================================================================================== + # Identifies the latest version of the formula and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. # rubocop:disable Metrics/CyclomaticComplexity From 1ee4f1a696e82d3f1c89313a4978ebce1a1d09b9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 17:39:07 +0200 Subject: [PATCH 019/111] Work in progress for extending livecheck command for resources --- Library/Homebrew/livecheck/livecheck.rb | 330 +++++++++++++----------- 1 file changed, 173 insertions(+), 157 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 854666816d..13f3a435b8 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -485,9 +485,11 @@ module Homebrew when String livecheck_url when :url - package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) + package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable - package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) || package_or_resource.is_a?(Resource) + # Not sure how to handle this ? + # Do I have to add :stable / :head in Resources' as well (like it's being implemented in Formula ?) + package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage package_or_resource.homepage end @@ -500,12 +502,7 @@ module Homebrew case package_or_resource when Resource - if package_or_resource.stable - urls << package_or_resource.stable.url - urls.concat(package_or_resource.stable.mirrors) - end - urls << package_or_resource.head.url if package_or_resource.head - urls << package_or_resource.homepage if package_or_resource.homepage + urls << package_or_resource.url when Formula if package_or_resource.stable urls << package_or_resource.stable.url @@ -623,6 +620,11 @@ module Homebrew formula_with_resources.resources.each_with_index do |resource, i| has_livecheckable = resource.livecheckable? + if debug + puts "Resource: #{resource_name(resource, full_name: full_name)}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + end + #@todo: for now, only check resources with livecheck block if has_livecheckable livecheck = resource.livecheck @@ -640,12 +642,165 @@ module Homebrew urls = [livecheck_url_string] if livecheck_url_string urls ||= checkable_urls(resource) + puts "URLs: #{urls}" + + checked_urls = [] + + urls.each_with_index do |original_url, i| + # Only preprocess the URL when it's appropriate + url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + original_url + else + preprocess_url(original_url) + end + next if checked_urls.include?(url) + + + strategies = Strategy.from_url( + url, + livecheck_strategy: livecheck_strategy, + url_provided: livecheck_url.present?, + regex_provided: livecheck_regex.present?, + block_provided: livecheck_strategy_block.present?, + ) + + strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + strategy_name = livecheck_strategy_names[strategy] + + if debug + puts + if livecheck_url.is_a?(Symbol) + # This assumes the URL symbol will fit within the available space + puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url + else + puts "URL: #{original_url}" + end + puts "URL (processed): #{url}" if url != original_url + if strategies.present? && verbose + puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" + end + puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + end + + if livecheck_strategy.present? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + odebug "#{strategy_name} strategy requires a URL" + next + elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + odebug "#{strategy_name} strategy does not apply to this URL" + next + end + end + + next if strategy.blank? + homebrew_curl = case strategy_name + when "PageMatch", "HeaderMatch" + use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) + end + puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? + + # p "strategy.method(:find_versions).parameters: #{strategy.method(:find_versions).parameters}" + + strategy_data = strategy.find_versions( + url: url, + regex: livecheck_regex, + homebrew_curl: homebrew_curl, + &livecheck_strategy_block + ) + + # p strategy_data + + match_version_map = strategy_data[:matches] + p "match_version_map: #{match_version_map}" + regex = strategy_data[:regex] + messages = strategy_data[:messages] + checked_urls << url + + if messages.is_a?(Array) && match_version_map.blank? + puts messages unless json + next if i + 1 < urls.length + + return status_hash(formula_or_cask, "error", messages, full_name: full_name, verbose: verbose) + end + + if debug + if strategy_data[:url].present? && strategy_data[:url] != url + puts "URL (strategy): #{strategy_data[:url]}" + end + puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + puts "Regex (strategy): #{strategy_data[:regex].inspect}" + end + puts "Cached?: Yes" if strategy_data[:cached] == true + end + + match_version_map.delete_if do |_match, version| + next true if version.blank? + next false if has_livecheckable + + UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + version.to_s.include?(rejection) + end + end + + next if match_version_map.blank? + + if debug + puts + puts "Matched Versions:" + + if verbose + match_version_map.each do |match, version| + puts "#{match} => #{version.inspect}" + end + else + puts match_version_map.values.join(", ") + end + end + + version_info = { + latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), + } + + if json && verbose + version_info[:meta] = {} + + if livecheck_references.present? + version_info[:meta][:references] = livecheck_references.map do |ref_formula_or_cask| + case ref_formula_or_cask + when Formula + { formula: formula_name(ref_formula_or_cask, full_name: full_name) } + when Cask::Cask + { cask: cask_name(ref_formula_or_cask, full_name: full_name) } + end + end + end + + version_info[:meta][:url] = {} + version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + version_info[:meta][:url][:original] = original_url + version_info[:meta][:url][:processed] = url if url != original_url + if strategy_data[:url].present? && strategy_data[:url] != url + version_info[:meta][:url][:strategy] = strategy_data[:url] + end + version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + + version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil + version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? + version_info[:meta][:regex] = regex.inspect if regex.present? + version_info[:meta][:cached] = true if strategy_data[:cached] == true + end + + puts "Version Info: #{}" + + return version_info + end + + end - if debug - puts "Resource: #{resource_name(resource, full_name: full_name)}" - puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" - end end @@ -654,152 +809,9 @@ module Homebrew - # checked_urls = [] - # # rubocop:disable Metrics/BlockLength - # urls.each_with_index do |original_url, i| - # # Only preprocess the URL when it's appropriate - # url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) - # original_url - # else - # preprocess_url(original_url) - # end - # next if checked_urls.include?(url) + # rubocop:disable Metrics/BlockLength - # strategies = Strategy.from_url( - # url, - # livecheck_strategy: livecheck_strategy, - # url_provided: livecheck_url.present?, - # regex_provided: livecheck_regex.present?, - # block_provided: livecheck_strategy_block.present?, - # ) - # strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first - # strategy_name = livecheck_strategy_names[strategy] - - # if debug - # puts - # if livecheck_url.is_a?(Symbol) - # # This assumes the URL symbol will fit within the available space - # puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url - # else - # puts "URL: #{original_url}" - # end - # puts "URL (processed): #{url}" if url != original_url - # if strategies.present? && verbose - # puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" - # end - # puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" - # puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? - # end - - # if livecheck_strategy.present? - # if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) - # odebug "#{strategy_name} strategy requires a URL" - # next - # elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) - # odebug "#{strategy_name} strategy does not apply to this URL" - # next - # end - # end - - # next if strategy.blank? - - # homebrew_curl = case strategy_name - # when "PageMatch", "HeaderMatch" - # use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) - # end - # puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - - # strategy_data = strategy.find_versions( - # url: url, - # regex: livecheck_regex, - # homebrew_curl: homebrew_curl, - # cask: cask, - # &livecheck_strategy_block - # ) - # match_version_map = strategy_data[:matches] - # regex = strategy_data[:regex] - # messages = strategy_data[:messages] - # checked_urls << url - - # if messages.is_a?(Array) && match_version_map.blank? - # puts messages unless json - # next if i + 1 < urls.length - - # return status_hash(formula_or_cask, "error", messages, full_name: full_name, verbose: verbose) - # end - - # if debug - # if strategy_data[:url].present? && strategy_data[:url] != url - # puts "URL (strategy): #{strategy_data[:url]}" - # end - # puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? - # if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex - # puts "Regex (strategy): #{strategy_data[:regex].inspect}" - # end - # puts "Cached?: Yes" if strategy_data[:cached] == true - # end - - # match_version_map.delete_if do |_match, version| - # next true if version.blank? - # next false if has_livecheckable - - # UNSTABLE_VERSION_KEYWORDS.any? do |rejection| - # version.to_s.include?(rejection) - # end - # end - - # next if match_version_map.blank? - - # if debug - # puts - # puts "Matched Versions:" - - # if verbose - # match_version_map.each do |match, version| - # puts "#{match} => #{version.inspect}" - # end - # else - # puts match_version_map.values.join(", ") - # end - # end - - # version_info = { - # latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), - # } - - # if json && verbose - # version_info[:meta] = {} - - # if livecheck_references.present? - # version_info[:meta][:references] = livecheck_references.map do |ref_formula_or_cask| - # case ref_formula_or_cask - # when Formula - # { formula: formula_name(ref_formula_or_cask, full_name: full_name) } - # when Cask::Cask - # { cask: cask_name(ref_formula_or_cask, full_name: full_name) } - # end - # end - # end - - # version_info[:meta][:url] = {} - # version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string - # version_info[:meta][:url][:original] = original_url - # version_info[:meta][:url][:processed] = url if url != original_url - # if strategy_data[:url].present? && strategy_data[:url] != url - # version_info[:meta][:url][:strategy] = strategy_data[:url] - # end - # version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - # version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - - # version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil - # version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? - # version_info[:meta][:regex] = regex.inspect if regex.present? - # version_info[:meta][:cached] = true if strategy_data[:cached] == true - # end - - # return version_info - # end - # rubocop:enable Metrics/BlockLength + #rubocop:enable Metrics/BlockLength nil end @@ -927,7 +939,11 @@ module Homebrew cask: cask, &livecheck_strategy_block ) + + # p strategy_data + match_version_map = strategy_data[:matches] + p "match_version_map: #{match_version_map}" regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url From a60cd0097334717a287142d77db9353bcaf6dd3b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 19:54:00 +0200 Subject: [PATCH 020/111] Minor: added version_info for resources --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 13f3a435b8..88ce4a2979 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -760,7 +760,7 @@ module Homebrew end version_info = { - latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), + latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }), } if json && verbose @@ -793,7 +793,7 @@ module Homebrew version_info[:meta][:cached] = true if strategy_data[:cached] == true end - puts "Version Info: #{}" + puts "Version Info: #{version_info}" return version_info end From 7ce15eaa60dd5552c15f851252507cbce6a8d528 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 25 Jul 2022 00:56:36 +0200 Subject: [PATCH 021/111] Basic debug info --- Library/Homebrew/livecheck/livecheck.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 88ce4a2979..5ac3258ef0 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -353,7 +353,13 @@ module Homebrew next info end - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + if resources_only + #@todo: modify print_latest_version for resources + onoe "#{Tty.blue}Debug info for resources is in progress!#{Tty.reset}" + else + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + end + nil rescue => e Homebrew.failed = true @@ -489,7 +495,7 @@ module Homebrew when :head, :stable # Not sure how to handle this ? # Do I have to add :stable / :head in Resources' as well (like it's being implemented in Formula ?) - package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) + package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) || package_or_resource.is_a?(Resource) when :homepage package_or_resource.homepage end From 43fcb5e563553d7450601950ed9fc97ab4e7b9ef Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 13:26:48 +0200 Subject: [PATCH 022/111] Added support for resources in LivecheckVersion --- Library/Homebrew/livecheck/livecheck_version.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck_version.rb b/Library/Homebrew/livecheck/livecheck_version.rb index 80336076e7..f1b722ed49 100644 --- a/Library/Homebrew/livecheck/livecheck_version.rb +++ b/Library/Homebrew/livecheck/livecheck_version.rb @@ -11,15 +11,17 @@ module Homebrew include Comparable - sig { params(formula_or_cask: T.any(Formula, Cask::Cask), version: Version).returns(LivecheckVersion) } - def self.create(formula_or_cask, version) - versions = case formula_or_cask + sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), version: Version).returns(LivecheckVersion) } + def self.create(package_or_resource, version) + versions = case package_or_resource + when Resource + [version] when Formula [version] when Cask::Cask version.to_s.split(/[,:]/).map { |s| Version.new(s) } else - T.absurd(formula_or_cask) + T.absurd(package_or_resource) end new(versions) end From e84cc8d116e6e921ce9a93fbf66cdd54cca12829 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 13:27:21 +0200 Subject: [PATCH 023/111] Work in progress for livecheckable resources --- Library/Homebrew/livecheck/livecheck.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 5ac3258ef0..052bfa839a 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -493,9 +493,11 @@ module Homebrew when :url package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable + # Resource's "url" is considered "stable" by default. And some resources may contain in "head" block as well + package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) # Not sure how to handle this ? # Do I have to add :stable / :head in Resources' as well (like it's being implemented in Formula ?) - package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) || package_or_resource.is_a?(Resource) + package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage package_or_resource.homepage end @@ -702,7 +704,7 @@ module Homebrew next if strategy.blank? homebrew_curl = case strategy_name when "PageMatch", "HeaderMatch" - use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) + use_homebrew_curl?(resource, url) end puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? From 32659afdbe0f4486ea1f6494882af0ffc86e9eaa Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 13:53:54 +0200 Subject: [PATCH 024/111] Updated livecheck command for resources --- Library/Homebrew/dev-cmd/livecheck.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index de7a343b9d..94cd1b3527 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -69,10 +69,10 @@ module Homebrew formulae = args.cask? ? [] : Formula.installed casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks - elsif args.resources? - # formula_with_resources = Formula.all.select { |formula| formula.resources.any? } - formula_with_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } - formula_with_resources + # elsif args.resources? + # # formula_with_resources = Formula.all.select { |formula| formula.resources.any? } + # formula_with_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } + # formula_with_resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all @@ -83,7 +83,7 @@ module Homebrew elsif args.cask? args.named.to_casks else - args.named.to_package_and_resource + args.named.to_formulae_and_casks end elsif File.exist?(WATCHLIST_PATH) begin @@ -92,7 +92,7 @@ module Homebrew .map(&:strip) named_args = T.unsafe(CLI::NamedArgs).new(*names, parent: args) - named_args.to_package_and_resource(ignore_unavailable: true) + named_args.to_formulae_and_casks(ignore_unavailable: true) rescue Errno::ENOENT => e onoe e end @@ -115,7 +115,7 @@ module Homebrew json: args.json?, full_name: args.full_name?, handle_name_conflict: !args.formula? && !args.cask?, - resources_only: args.resources?, + check_resources: args.resources?, newer_only: args.newer_only?, quiet: args.quiet?, debug: args.debug?, From 277761009540b7fc3f6d2fdbbe922903631b2890 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 13:54:20 +0200 Subject: [PATCH 025/111] Work in progress for `resource_version` --- Library/Homebrew/livecheck/livecheck.rb | 51 +++++++++++-------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 052bfa839a..02b66e2207 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -162,7 +162,7 @@ module Homebrew formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], full_name: T::Boolean, handle_name_conflict: T::Boolean, - resources_only: T::Boolean, + check_resources: T::Boolean, json: T::Boolean, newer_only: T::Boolean, debug: T::Boolean, @@ -172,7 +172,7 @@ module Homebrew } def run_checks( formulae_and_casks_to_check, - full_name: false, handle_name_conflict: false, resources_only: false, json: false, newer_only: false, + full_name: false, handle_name_conflict: false, check_resources: false, json: false, newer_only: false, debug: false, quiet: false, verbose: false ) load_other_tap_strategies(formulae_and_casks_to_check) @@ -280,25 +280,24 @@ module Homebrew latest = if formula&.head_only? formula.head.downloader.fetch_last_commit else - if resources_only - version_info = resource_version( + version_info = latest_version( + formula_or_cask, + referenced_formula_or_cask: referenced_formula_or_cask, + livecheck_references: livecheck_references, + json: json, full_name: use_full_name, verbose: verbose, debug: debug + ) + version_info[:latest] if version_info.present? + + # In case "--resources" flag is passed as well + if check_resources + resource_version_info = resource_version( formula_or_cask, - referenced_formula: referenced_formula_or_cask, - livecheck_references: livecheck_references, json: json, full_name: use_full_name, verbose: verbose, debug: debug ) - else - version_info = latest_version( - formula_or_cask, - referenced_formula_or_cask: referenced_formula_or_cask, - livecheck_references: livecheck_references, - json: json, full_name: use_full_name, verbose: verbose, debug: debug - ) end - version_info[:latest] if version_info.present? end if latest.blank? @@ -353,7 +352,7 @@ module Homebrew next info end - if resources_only + if check_resources #@todo: modify print_latest_version for resources onoe "#{Tty.blue}Debug info for resources is in progress!#{Tty.reset}" else @@ -607,9 +606,7 @@ module Homebrew # the version information. Returns nil if a latest version couldn't be found. sig { params( - formula_with_resources: T.any(Formula), - referenced_formula: T.nilable(T.any(Formula)), - livecheck_references: T::Array[T.any(Formula, Cask::Cask)], + formula_or_cask: T.any(Formula, Cask::Cask), json: T::Boolean, full_name: T::Boolean, verbose: T::Boolean, @@ -617,26 +614,23 @@ module Homebrew ).returns(T.nilable(Hash)) } def resource_version( - formula_with_resources, - referenced_formula: nil, - livecheck_references: [], + formula_or_cask, json: false, full_name: false, verbose: false, debug: false ) - formula_with_resources.resources.each_with_index do |resource, i| + formula_or_cask.resources.each_with_index do |resource, i| has_livecheckable = resource.livecheckable? if debug - puts "Resource: #{resource_name(resource, full_name: full_name)}" - puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + odebug "Resource: #{resource_name(resource, full_name: full_name)}" + odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end - #@todo: for now, only check resources with livecheck block + # For now, only check resources with livecheck block if has_livecheckable livecheck = resource.livecheck - # referenced_livecheck = referenced_formula_or_cask&.livecheck livecheck_url = livecheck.url livecheck_regex = livecheck.regex livecheck_strategy = livecheck.strategy @@ -650,7 +644,9 @@ module Homebrew urls = [livecheck_url_string] if livecheck_url_string urls ||= checkable_urls(resource) - puts "URLs: #{urls}" + if debug + odebug "URLs: #{urls}" + end checked_urls = [] @@ -663,7 +659,6 @@ module Homebrew end next if checked_urls.include?(url) - strategies = Strategy.from_url( url, livecheck_strategy: livecheck_strategy, From e72487c8b07e59cba0d3dd1b1ed45bedc73a2592 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 15:13:55 +0200 Subject: [PATCH 026/111] Updated for current and latest versions for resources --- Library/Homebrew/livecheck/livecheck.rb | 105 ++++++++++++------------ 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 02b66e2207..0ce88ec1b3 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -287,9 +287,23 @@ module Homebrew json: json, full_name: use_full_name, verbose: verbose, debug: debug ) version_info[:latest] if version_info.present? + end + + # Check current and latest resources (if "--resources" flag is given) + if check_resources + + has_resources = formula_or_cask.resources.any? + + # In case we don't have any resources for that Formula/Cask + if !has_resources && (debug || verbose) + onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" + end + + # Only check current and latest versions of resources if we have resources to check against + if has_resources + + current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version } } - # In case "--resources" flag is passed as well - if check_resources resource_version_info = resource_version( formula_or_cask, json: json, @@ -297,6 +311,19 @@ module Homebrew verbose: verbose, debug: debug ) + + latest_resources = resource_version_info.map { |resource| { name: resource.name, version: resource.latest } } + + + + end + + + + + if debug && has_resources + odebug "Current Resources: #{current_resources}" + odebug "Latest Resources: #{latest_resources}" end end @@ -703,8 +730,6 @@ module Homebrew end puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - # p "strategy.method(:find_versions).parameters: #{strategy.method(:find_versions).parameters}" - strategy_data = strategy.find_versions( url: url, regex: livecheck_regex, @@ -712,10 +737,10 @@ module Homebrew &livecheck_strategy_block ) - # p strategy_data - match_version_map = strategy_data[:matches] - p "match_version_map: #{match_version_map}" + if debug + odebug "match_version_map: #{match_version_map}" + end regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url @@ -762,60 +787,36 @@ module Homebrew end end - version_info = { + resource_version_info = { + name: resource_name(resource, full_name: full_name), latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }), } if json && verbose - version_info[:meta] = {} - - if livecheck_references.present? - version_info[:meta][:references] = livecheck_references.map do |ref_formula_or_cask| - case ref_formula_or_cask - when Formula - { formula: formula_name(ref_formula_or_cask, full_name: full_name) } - when Cask::Cask - { cask: cask_name(ref_formula_or_cask, full_name: full_name) } - end - end - end - - version_info[:meta][:url] = {} - version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string - version_info[:meta][:url][:original] = original_url - version_info[:meta][:url][:processed] = url if url != original_url + resource_version_info[:meta] = {} + resource_version_info[:meta][:name] = resource_name(resource, full_name: full_name) if resource + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + resource_version_info[:meta][:url] = {} + resource_version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url][:processed] = url if url != original_url if strategy_data[:url].present? && strategy_data[:url] != url - version_info[:meta][:url][:strategy] = strategy_data[:url] + resource_version_info[:meta][:url][:strategy] = strategy_data[:url] end - version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - - version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil - version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? - version_info[:meta][:regex] = regex.inspect if regex.present? - version_info[:meta][:cached] = true if strategy_data[:cached] == true + resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + resource_version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil + resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? + resource_version_info[:meta][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true end - - puts "Version Info: #{version_info}" - - return version_info + if debug + odebug "Resource Version Info: #{resource_version_info}" + end + return resource_version_info end - - end - - end - - - - - - - # rubocop:disable Metrics/BlockLength - - #rubocop:enable Metrics/BlockLength - nil end @@ -946,7 +947,7 @@ module Homebrew # p strategy_data match_version_map = strategy_data[:matches] - p "match_version_map: #{match_version_map}" + # p "match_version_map: #{match_version_map}" regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url From 73cf8fd2059464ee8de29097e1506a14e99d939a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 15:24:33 +0200 Subject: [PATCH 027/111] Updated latest version for resources --- Library/Homebrew/livecheck/livecheck.rb | 32 ++++++++++++------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 0ce88ec1b3..e6a466280f 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -294,11 +294,6 @@ module Homebrew has_resources = formula_or_cask.resources.any? - # In case we don't have any resources for that Formula/Cask - if !has_resources && (debug || verbose) - onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" - end - # Only check current and latest versions of resources if we have resources to check against if has_resources @@ -312,18 +307,20 @@ module Homebrew debug: debug ) - latest_resources = resource_version_info.map { |resource| { name: resource.name, version: resource.latest } } + odebug "resource_version_info: #{resource_version_info}" + # latest_resources = resource_version_info.map { |resource| { name: resource.name, version: resource.latest } } + if debug || verbose + odebug "Current Resources: #{current_resources}" + odebug "Latest Resources: #{latest_resources}" + end - end - - - - - if debug && has_resources - odebug "Current Resources: #{current_resources}" - odebug "Latest Resources: #{latest_resources}" + else + # In case we don't have any resources for that Formula/Cask + if debug || verbose + onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" + end end end @@ -638,7 +635,7 @@ module Homebrew full_name: T::Boolean, verbose: T::Boolean, debug: T::Boolean, - ).returns(T.nilable(Hash)) + ).returns(Array(T.nilable(Hash))) } def resource_version( formula_or_cask, @@ -647,6 +644,7 @@ module Homebrew verbose: false, debug: false ) + resources_version = [] formula_or_cask.resources.each_with_index do |resource, i| has_livecheckable = resource.livecheckable? @@ -813,11 +811,11 @@ module Homebrew if debug odebug "Resource Version Info: #{resource_version_info}" end - return resource_version_info + resources_version << resource_version_info end end end - nil + resources_version end #================================================================================== From 8e3e9743ac4deb57117de84c625192638d7ee272 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 16:37:31 +0200 Subject: [PATCH 028/111] Basic structure completed for livecheckable resources --- Library/Homebrew/livecheck/livecheck.rb | 81 +++++++++++++++++++++++-- Library/Taps/homebrew/homebrew-core | 2 +- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e6a466280f..84fbe9fdf1 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -297,7 +297,7 @@ module Homebrew # Only check current and latest versions of resources if we have resources to check against if has_resources - current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version } } + current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } } resource_version_info = resource_version( formula_or_cask, @@ -307,11 +307,16 @@ module Homebrew debug: debug ) - odebug "resource_version_info: #{resource_version_info}" + # odebug "resource_version_info: #{resource_version_info}" - # latest_resources = resource_version_info.map { |resource| { name: resource.name, version: resource.latest } } + latest_resources = resource_version_info.map { |resource| { name: resource[:name], version: resource[:latest] } } if debug || verbose + puts <<~EOS + + ---------- + + EOS odebug "Current Resources: #{current_resources}" odebug "Latest Resources: #{latest_resources}" end @@ -377,8 +382,43 @@ module Homebrew end if check_resources + + resources_info = [] + + if has_resources + latest_resources_names = latest_resources.map { |r| r[:name] } + current_resources.each_with_index do |resource, i| + + current = resource[:version] + current_str = current.to_s + latest = if latest_resources_names.include?(resource[:name].to_s) + res = latest_resources.detect { |r| r[:name].to_s == resource[:name].to_s } + res[:version] + else + current + end + latest_str = latest.to_s + + is_newer_than_upstream = current > latest + is_outdated = (current != latest) && !is_newer_than_upstream + + info = {} + info[:resource] = resource[:name] + info[:livecheckable] = resource[:livecheckable] + info[:version] = { + current: current_str, + latest: latest_str, + newer_than_upstream: is_newer_than_upstream, + outdated: is_outdated, + } + resources_info << info + end + end + + #@todo: modify print_latest_version for resources onoe "#{Tty.blue}Debug info for resources is in progress!#{Tty.reset}" + print_latest_resource_version(resources_info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) else print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) end @@ -481,6 +521,30 @@ module Homebrew status_hash end + # Formats and prints the livecheck result for a resource (for a given Formula or Cask). + sig { params(resources_info: Array(Hash), verbose: T::Boolean, ambiguous_cask: T::Boolean).void } + def print_latest_resource_version(resources_info, verbose:, ambiguous_cask: false) + odebug "resources_info: #{resources_info}" + resources_info.each_with_index do |info, i| + resource_s = "#{Tty.blue}#{info[:resource]}#{Tty.reset}" + resource_s += " (livecheckable)" if info[:livecheckable] && verbose + + current_s = if info[:version][:newer_than_upstream] + "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" + else + info[:version][:current] + end + + latest_s = if info[:version][:outdated] + "#{Tty.green}#{info[:version][:latest]}#{Tty.reset}" + else + info[:version][:latest] + end + + puts "#{resource_s}: #{current_s} ==> #{latest_s}" + end + end + # Formats and prints the livecheck result for a formula. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void } def print_latest_version(info, verbose:, ambiguous_cask: false) @@ -649,6 +713,11 @@ module Homebrew has_livecheckable = resource.livecheckable? if debug + puts <<~EOS + + ---------- + + EOS odebug "Resource: #{resource_name(resource, full_name: full_name)}" odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end @@ -736,9 +805,9 @@ module Homebrew ) match_version_map = strategy_data[:matches] - if debug - odebug "match_version_map: #{match_version_map}" - end + # if debug + # odebug "match_version_map: #{match_version_map}" + # end regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url diff --git a/Library/Taps/homebrew/homebrew-core b/Library/Taps/homebrew/homebrew-core index 88b2623dd6..65b3469d30 160000 --- a/Library/Taps/homebrew/homebrew-core +++ b/Library/Taps/homebrew/homebrew-core @@ -1 +1 @@ -Subproject commit 88b2623dd6ff0dec391029b1f43107438935f4b7 +Subproject commit 65b3469d300943210a42d69f75eae33faafd204c From 1f55f15d664b3ed5ee8639de985847382a70f614 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 16:51:26 +0200 Subject: [PATCH 029/111] Removed extra bits --- Library/Homebrew/livecheck/livecheck.rb | 85 +++++++++---------------- 1 file changed, 29 insertions(+), 56 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 84fbe9fdf1..dd78146e0e 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -271,9 +271,6 @@ module Homebrew Version.new(formula_or_cask.version) end - p "Formula: #{formula_or_cask_name(formula_or_cask, full_name: use_full_name)}" - p "Current: #{current.to_s}" - current_str = current.to_s current = LivecheckVersion.create(formula_or_cask, current) @@ -307,20 +304,8 @@ module Homebrew debug: debug ) - # odebug "resource_version_info: #{resource_version_info}" - latest_resources = resource_version_info.map { |resource| { name: resource[:name], version: resource[:latest] } } - if debug || verbose - puts <<~EOS - - ---------- - - EOS - odebug "Current Resources: #{current_resources}" - odebug "Latest Resources: #{latest_resources}" - end - else # In case we don't have any resources for that Formula/Cask if debug || verbose @@ -381,46 +366,42 @@ module Homebrew next info end - if check_resources + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + if check_resources && has_resources resources_info = [] - - if has_resources - latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each_with_index do |resource, i| - - current = resource[:version] - current_str = current.to_s - latest = if latest_resources_names.include?(resource[:name].to_s) - res = latest_resources.detect { |r| r[:name].to_s == resource[:name].to_s } - res[:version] - else - current - end - latest_str = latest.to_s - - is_newer_than_upstream = current > latest - is_outdated = (current != latest) && !is_newer_than_upstream - - info = {} - info[:resource] = resource[:name] - info[:livecheckable] = resource[:livecheckable] - info[:version] = { - current: current_str, - latest: latest_str, - newer_than_upstream: is_newer_than_upstream, - outdated: is_outdated, - } - resources_info << info + latest_resources_names = latest_resources.map { |r| r[:name] } + current_resources.each_with_index do |resource, i| + current = resource[:version] + current_str = current.to_s + latest = if latest_resources_names.include?(resource[:name].to_s) + res = latest_resources.detect { |r| r[:name].to_s == resource[:name].to_s } + res[:version] + else + current end + latest_str = latest.to_s + + is_newer_than_upstream = current > latest + is_outdated = (current != latest) && !is_newer_than_upstream + + info = {} + info[:resource] = resource[:name] + info[:livecheckable] = resource[:livecheckable] + info[:version] = { + current: current_str, + latest: latest_str, + newer_than_upstream: is_newer_than_upstream, + outdated: is_outdated, + } + resources_info << info end + puts <<~EOS + ---------- - #@todo: modify print_latest_version for resources - onoe "#{Tty.blue}Debug info for resources is in progress!#{Tty.reset}" + EOS print_latest_resource_version(resources_info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) - else - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) end nil @@ -524,7 +505,6 @@ module Homebrew # Formats and prints the livecheck result for a resource (for a given Formula or Cask). sig { params(resources_info: Array(Hash), verbose: T::Boolean, ambiguous_cask: T::Boolean).void } def print_latest_resource_version(resources_info, verbose:, ambiguous_cask: false) - odebug "resources_info: #{resources_info}" resources_info.each_with_index do |info, i| resource_s = "#{Tty.blue}#{info[:resource]}#{Tty.reset}" resource_s += " (livecheckable)" if info[:livecheckable] && verbose @@ -738,10 +718,6 @@ module Homebrew urls = [livecheck_url_string] if livecheck_url_string urls ||= checkable_urls(resource) - if debug - odebug "URLs: #{urls}" - end - checked_urls = [] urls.each_with_index do |original_url, i| @@ -877,9 +853,6 @@ module Homebrew resource_version_info[:meta][:regex] = regex.inspect if regex.present? resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true end - if debug - odebug "Resource Version Info: #{resource_version_info}" - end resources_version << resource_version_info end end From a8c1c0c8412d8a1e6b64c15afeec198b8f21bcc9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 18:19:14 +0200 Subject: [PATCH 030/111] Updated description for resource's option in livecheck command --- Library/Homebrew/dev-cmd/livecheck.rb | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 94cd1b3527..966cd75a4f 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -36,7 +36,7 @@ module Homebrew switch "--json", description: "Output information in JSON format." switch "-r", "--resources", - description: "Check resources with livecheck blocks." + description: "Check resources with livecheck blocks for a given formulae/casks." switch "-q", "--quiet", description: "Suppress warnings, don't print a progress bar for JSON output." switch "--formula", "--formulae", @@ -69,10 +69,6 @@ module Homebrew formulae = args.cask? ? [] : Formula.installed casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks - # elsif args.resources? - # # formula_with_resources = Formula.all.select { |formula| formula.resources.any? } - # formula_with_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } - # formula_with_resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all @@ -100,11 +96,6 @@ module Homebrew raise UsageError, "A watchlist file is required when no arguments are given." end - # p package_and_resource_to_check.class - # p package_and_resource_to_check.length - # p package_and_resource_to_check[0].class - # p package_and_resource_to_check.map { |d| d.name } - package_and_resource_to_check = package_and_resource_to_check.sort_by do |package_or_resource| package_or_resource.respond_to?(:token) ? package_or_resource.token : package_or_resource.name end From 3dc1b9c231d9fb3b42ce7b4e2f2416863e7073ca Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 18:25:12 +0200 Subject: [PATCH 031/111] Refactored `run_checks` and `resource_version` methods for livecheck command --- Library/Homebrew/livecheck/livecheck.rb | 104 +++++++++++++----------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index dd78146e0e..131c03d332 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -254,9 +254,6 @@ module Homebrew formula&.head&.downloader&.shutup! - # Check resources if "--resources" flag was given - - # Use the `stable` version for comparison except for installed # head-only formulae. A formula with `stable` and `head` that's # installed using `--head` will still use the `stable` version for @@ -291,7 +288,7 @@ module Homebrew has_resources = formula_or_cask.resources.any? - # Only check current and latest versions of resources if we have resources to check against + # Only check current and latest versions if we have resources to check against if has_resources current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } } @@ -304,7 +301,7 @@ module Homebrew debug: debug ) - latest_resources = resource_version_info.map { |resource| { name: resource[:name], version: resource[:latest] } } + latest_resources = resource_version_info.map { |resource| { name: resource[:resource], version: resource[:version][:latest] } } else # In case we don't have any resources for that Formula/Cask @@ -356,6 +353,8 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) + info[:resources] = resource_version_info if check_resources + next if newer_only && !info[:version][:outdated] has_a_newer_upstream_version ||= true @@ -366,6 +365,13 @@ module Homebrew next info end + if check_resources && has_resources && debug + puts <<~EOS + + ---------- + + EOS + end print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) if check_resources && has_resources @@ -396,11 +402,6 @@ module Homebrew } resources_info << info end - puts <<~EOS - - ---------- - - EOS print_latest_resource_version(resources_info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) end @@ -474,28 +475,31 @@ module Homebrew sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), + package_or_resource: T.any(Formula, Cask::Cask, Resource), status_str: String, messages: T.nilable(T::Array[String]), full_name: T::Boolean, verbose: T::Boolean, ).returns(Hash) } - def status_hash(formula_or_cask, status_str, messages = nil, full_name: false, verbose: false) - formula = formula_or_cask if formula_or_cask.is_a?(Formula) - cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) + def status_hash(package_or_resource, status_str, messages = nil, full_name: false, verbose: false) + formula = package_or_resource if package_or_resource.is_a?(Formula) + cask = package_or_resource if package_or_resource.is_a?(Cask::Cask) + resource = package_or_resource if package_or_resource.is_a?(Resource) status_hash = {} if formula status_hash[:formula] = formula_name(formula, full_name: full_name) elsif cask - status_hash[:cask] = cask_name(formula_or_cask, full_name: full_name) + status_hash[:cask] = cask_name(package_or_resource, full_name: full_name) + elsif resource + status_hash[:resource] = resource_name(package_or_resource, full_name: full_name) end status_hash[:status] = status_str status_hash[:messages] = messages if messages.is_a?(Array) status_hash[:meta] = { - livecheckable: formula_or_cask.livecheckable?, + livecheckable: package_or_resource.livecheckable?, } status_hash[:meta][:head_only] = true if formula&.head_only? @@ -521,7 +525,7 @@ module Homebrew info[:version][:latest] end - puts "#{resource_s}: #{current_s} ==> #{latest_s}" + puts "-- #{resource_s}: #{current_s} ==> #{latest_s}" end end @@ -668,10 +672,8 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end - #================================================================================== - - # Identifies the latest version of the resources and returns a Hash containing - # the version information. Returns nil if a latest version couldn't be found. + # Identifies the latest version of the resources in a given Formulae/Casks and returns an Array of Hash containing + # the version information for all the resources. Returns an Array with nil value if a latest version couldn't be found for a given resource. sig { params( formula_or_cask: T.any(Formula, Cask::Cask), @@ -702,7 +704,14 @@ module Homebrew odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end - # For now, only check resources with livecheck block + resource_version_info = { + resource: resource_name(resource, full_name: full_name), + version: { + current: resource.version, + }, + } + + # Check resources with livecheck block (will be updated in the future) if has_livecheckable livecheck = resource.livecheck livecheck_url = livecheck.url @@ -781,9 +790,6 @@ module Homebrew ) match_version_map = strategy_data[:matches] - # if debug - # odebug "match_version_map: #{match_version_map}" - # end regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url @@ -792,7 +798,7 @@ module Homebrew puts messages unless json next if i + 1 < urls.length - return status_hash(formula_or_cask, "error", messages, full_name: full_name, verbose: verbose) + return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) end if debug @@ -830,38 +836,45 @@ module Homebrew end end - resource_version_info = { - name: resource_name(resource, full_name: full_name), - latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }), - } + resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) if json && verbose resource_version_info[:meta] = {} - resource_version_info[:meta][:name] = resource_name(resource, full_name: full_name) if resource resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + if has_livecheckable + resource_version_info[:meta][:livecheck] = {} + resource_version_info[:meta][:livecheck][:url] = {} + resource_version_info[:meta][:livecheck][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + if strategy_data[:url].present? && strategy_data[:url] != url + resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] + end + resource_version_info[:meta][:livecheck][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil + resource_version_info[:meta][:livecheck][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? + resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + + end resource_version_info[:meta][:url] = {} - resource_version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string resource_version_info[:meta][:url][:original] = original_url resource_version_info[:meta][:url][:processed] = url if url != original_url - if strategy_data[:url].present? && strategy_data[:url] != url - resource_version_info[:meta][:url][:strategy] = strategy_data[:url] - end - resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - resource_version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil - resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? - resource_version_info[:meta][:regex] = regex.inspect if regex.present? - resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true end - resources_version << resource_version_info end + resources_version << resource_version_info + else + # If there's no livecheck block in resource + resource_version_info[:version][:latest] = resource.version + if json && verbose + resource_version_info[:meta] = {} + resource_version_info[:meta][:url] = resource.url.to_s + end + resources_version << resource_version_info end end resources_version end - #================================================================================== - # Identifies the latest version of the formula and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. # rubocop:disable Metrics/CyclomaticComplexity @@ -984,10 +997,7 @@ module Homebrew &livecheck_strategy_block ) - # p strategy_data - match_version_map = strategy_data[:matches] - # p "match_version_map: #{match_version_map}" regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url From 08cd9cebbb50305285ba2a37bbaaa474e6baeb98 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 19:11:13 +0200 Subject: [PATCH 032/111] Revert back some changes --- .gitignore | 2 +- .vscode/settings.json | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 17c761af71..10401ee27f 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ /Library/Homebrew/test/junit /Library/Homebrew/test/fs_leak_log /Library/Homebrew/vendor/portable-ruby -#/Library/Taps +/Library/Taps /Library/PinnedTaps /Library/Homebrew/.byebug_history /Library/Homebrew/sorbet/rbi/hidden-definitions/errors.txt diff --git a/.vscode/settings.json b/.vscode/settings.json index fe8a066e21..865fc53af2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,7 +23,5 @@ "editor.codeActionsOnSave": { "source.fixAll.shellcheck": true, } - }, - "git.mergeEditor": true, - "merge-conflict.autoNavigateNextConflict.enabled": true + } } From 23ec9142c9999726a70aae87922ff15f62d40d3d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 19:16:02 +0200 Subject: [PATCH 033/111] Removed unnecessary files --- .../lib/sorbet-runtime.rb | 116 -- .../lib/types/_types.rb | 316 ----- .../lib/types/abstract_utils.rb | 50 - .../lib/types/boolean.rb | 8 - .../lib/types/compatibility_patches.rb | 93 -- .../lib/types/configuration.rb | 591 -------- .../lib/types/enum.rb | 377 ------ .../lib/types/generic.rb | 22 - .../lib/types/helpers.rb | 58 - .../lib/types/interface_wrapper.rb | 158 --- .../lib/types/non_forcing_constants.rb | 65 - .../lib/types/private/abstract/data.rb | 36 - .../lib/types/private/abstract/declare.rb | 53 - .../lib/types/private/abstract/hooks.rb | 42 - .../lib/types/private/abstract/validate.rb | 128 -- .../lib/types/private/casts.rb | 41 - .../lib/types/private/class_utils.rb | 110 -- .../lib/types/private/compiler.rb | 24 - .../lib/types/private/decl_state.rb | 30 - .../lib/types/private/final.rb | 50 - .../lib/types/private/methods/_methods.rb | 581 -------- .../types/private/methods/call_validation.rb | 221 --- .../private/methods/call_validation_2_6.rb | 1203 ----------------- .../private/methods/call_validation_2_7.rb | 1203 ----------------- .../lib/types/private/methods/decl_builder.rb | 232 ---- .../lib/types/private/methods/modes.rb | 28 - .../lib/types/private/methods/signature.rb | 225 --- .../private/methods/signature_validation.rb | 225 --- .../lib/types/private/mixins/mixins.rb | 27 - .../lib/types/private/retry.rb | 10 - .../lib/types/private/runtime_levels.rb | 62 - .../lib/types/private/sealed.rb | 91 -- .../lib/types/private/types/not_typed.rb | 23 - .../lib/types/private/types/string_holder.rb | 26 - .../lib/types/private/types/type_alias.rb | 31 - .../lib/types/private/types/void.rb | 34 - .../lib/types/props/_props.rb | 169 --- .../lib/types/props/constructor.rb | 40 - .../lib/types/props/custom_type.rb | 108 -- .../lib/types/props/decorator.rb | 669 --------- .../lib/types/props/errors.rb | 8 - .../types/props/generated_code_validation.rb | 277 ---- .../props/has_lazily_specialized_methods.rb | 140 -- .../lib/types/props/optional.rb | 89 -- .../lib/types/props/plugin.rb | 37 - .../lib/types/props/pretty_printable.rb | 107 -- .../lib/types/props/private/apply_default.rb | 170 --- .../props/private/deserializer_generator.rb | 160 --- .../lib/types/props/private/parser.rb | 32 - .../types/props/private/serde_transform.rb | 186 --- .../props/private/serializer_generator.rb | 76 -- .../lib/types/props/private/setter_factory.rb | 197 --- .../lib/types/props/serializable.rb | 374 ----- .../lib/types/props/type_validation.rb | 111 -- .../lib/types/props/utils.rb | 59 - .../lib/types/props/weak_constructor.rb | 67 - .../sorbet-runtime-0.5.10132/lib/types/sig.rb | 30 - .../lib/types/struct.rb | 18 - .../lib/types/types/attached_class.rb | 37 - .../lib/types/types/base.rb | 172 --- .../lib/types/types/class_of.rb | 40 - .../lib/types/types/enum.rb | 40 - .../lib/types/types/fixed_array.rb | 86 -- .../lib/types/types/fixed_hash.rb | 74 - .../lib/types/types/intersection.rb | 42 - .../lib/types/types/noreturn.rb | 29 - .../lib/types/types/proc.rb | 51 - .../lib/types/types/self_type.rb | 35 - .../lib/types/types/simple.rb | 94 -- .../lib/types/types/t_enum.rb | 38 - .../lib/types/types/type_member.rb | 7 - .../lib/types/types/type_parameter.rb | 23 - .../lib/types/types/type_template.rb | 7 - .../lib/types/types/type_variable.rb | 34 - .../lib/types/types/typed_array.rb | 39 - .../lib/types/types/typed_enumerable.rb | 176 --- .../lib/types/types/typed_enumerator.rb | 41 - .../lib/types/types/typed_enumerator_lazy.rb | 41 - .../lib/types/types/typed_hash.rb | 48 - .../lib/types/types/typed_range.rb | 31 - .../lib/types/types/typed_set.rb | 53 - .../lib/types/types/union.rb | 91 -- .../lib/types/types/untyped.rb | 29 - .../lib/types/utils.rb | 209 --- 84 files changed, 11281 deletions(-) delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb deleted file mode 100644 index c2ad5678d0..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb +++ /dev/null @@ -1,116 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# This file is hand-crafted to encode the dependencies. They load the whole type -# system since there is such a high chance of it being used, using an autoloader -# wouldn't buy us any startup time saving. - -# Namespaces without any implementation -module T; end -module T::Helpers; end -module T::Private; end -module T::Private::Abstract; end -module T::Private::Types; end - -# Each section is a group that I believe need a fixed ordering. There is also -# an ordering between groups. - -# These are pre-reqs for almost everything in here. -require_relative 'types/configuration' -require_relative 'types/_types' -require_relative 'types/private/decl_state' -require_relative 'types/private/class_utils' -require_relative 'types/private/runtime_levels' -require_relative 'types/private/methods/_methods' -require_relative 'types/sig' -require_relative 'types/helpers' -require_relative 'types/private/final' -require_relative 'types/private/sealed' - -# The types themselves. First base classes -require_relative 'types/types/base' -require_relative 'types/types/typed_enumerable' -# Everything else -require_relative 'types/types/class_of' -require_relative 'types/types/enum' -require_relative 'types/types/fixed_array' -require_relative 'types/types/fixed_hash' -require_relative 'types/types/intersection' -require_relative 'types/types/noreturn' -require_relative 'types/types/proc' -require_relative 'types/types/attached_class' -require_relative 'types/types/self_type' -require_relative 'types/types/simple' -require_relative 'types/types/t_enum' -require_relative 'types/types/type_parameter' -require_relative 'types/types/typed_array' -require_relative 'types/types/typed_enumerator' -require_relative 'types/types/typed_enumerator_lazy' -require_relative 'types/types/typed_hash' -require_relative 'types/types/typed_range' -require_relative 'types/types/typed_set' -require_relative 'types/types/union' -require_relative 'types/types/untyped' -require_relative 'types/private/types/not_typed' -require_relative 'types/private/types/void' -require_relative 'types/private/types/string_holder' -require_relative 'types/private/types/type_alias' - -require_relative 'types/types/type_variable' -require_relative 'types/types/type_member' -require_relative 'types/types/type_template' - -# Call validation -require_relative 'types/private/methods/modes' -require_relative 'types/private/methods/call_validation' - -# Signature validation -require_relative 'types/private/methods/signature_validation' -require_relative 'types/abstract_utils' -require_relative 'types/private/abstract/validate' - -# Catch all. Sort of built by `cd extn; find types -type f | grep -v test | sort` -require_relative 'types/generic' -require_relative 'types/interface_wrapper' -require_relative 'types/private/abstract/declare' -require_relative 'types/private/abstract/hooks' -require_relative 'types/private/casts' -require_relative 'types/private/methods/decl_builder' -require_relative 'types/private/methods/signature' -require_relative 'types/private/retry' -require_relative 'types/utils' -require_relative 'types/boolean' - -# Props dependencies -require_relative 'types/private/abstract/data' -require_relative 'types/private/mixins/mixins' -require_relative 'types/props/_props' -require_relative 'types/props/custom_type' -require_relative 'types/props/decorator' -require_relative 'types/props/errors' -require_relative 'types/props/plugin' -require_relative 'types/props/utils' -require_relative 'types/enum' -# Props that run sigs statically so have to be after all the others :( -require_relative 'types/props/private/setter_factory' -require_relative 'types/props/private/apply_default' -require_relative 'types/props/has_lazily_specialized_methods' -require_relative 'types/props/optional' -require_relative 'types/props/weak_constructor' -require_relative 'types/props/constructor' -require_relative 'types/props/pretty_printable' -require_relative 'types/props/private/serde_transform' -require_relative 'types/props/private/deserializer_generator' -require_relative 'types/props/private/serializer_generator' -require_relative 'types/props/serializable' -require_relative 'types/props/type_validation' -require_relative 'types/props/private/parser' -require_relative 'types/props/generated_code_validation' - -require_relative 'types/struct' -require_relative 'types/non_forcing_constants' - -require_relative 'types/compatibility_patches' - -# Sorbet Compiler support module -require_relative 'types/private/compiler' diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb deleted file mode 100644 index 20a0e641e0..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb +++ /dev/null @@ -1,316 +0,0 @@ -# frozen_string_literal: true -# typed: true -# This is where we define the shortcuts, so we can't use them here - -# _____ -# |_ _| _ _ __ ___ ___ -# | || | | | '_ \ / _ \/ __| -# | || |_| | |_) | __/\__ \ -# |_| \__, | .__/ \___||___/ -# |___/|_| -# -# Docs at https://sorbet.org/docs/sigs -# -# Types that you can pass to `sig`: -# -# - a Ruby class -# -# - [, , ...] -- to specify a "tuple"; a fixed-size array with known types for each member -# -# - {key: , key2: , ...} -- to speicfy a "shape"; a fixed-size hash -# with known keys and type values -# -# - Any of the `T.foo` methods below - -module T - # T.any(, , ...) -- matches any of the types listed - 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? - T::Types::Union::Private::Pool.union_of_types(type_a, type_b, types) - end - - # Shorthand for T.any(type, NilClass) - def self.nilable(type) - T::Types::Union::Private::Pool.union_of_types(T::Utils.coerce(type), T::Utils::Nilable::NIL_TYPE) - end - - # Matches any object. In the static checker, T.untyped allows any - # method calls or operations. - def self.untyped - T::Types::Untyped::Private::INSTANCE - end - - # Indicates a function never returns (e.g. "Kernel#raise") - def self.noreturn - T::Types::NoReturn::Private::INSTANCE - end - - # T.all(, , ...) -- matches an object that has all of the types listed - def self.all(type_a, type_b, *types) - T::Types::Intersection.new([type_a, type_b] + types) - end - - # Matches any of the listed values - # @deprecated Use T::Enum instead. - def self.deprecated_enum(values) - T::Types::Enum.new(values) - end - - # Creates a proc type - def self.proc - T::Private::Methods.start_proc - end - - # Matches `self`: - def self.self_type - T::Types::SelfType::Private::INSTANCE - end - - # Matches the instance type in a singleton-class context - def self.attached_class - T::Types::AttachedClassType::Private::INSTANCE - end - - # Matches any class that subclasses or includes the provided class - # or module - def self.class_of(klass) - T::Types::ClassOf.new(klass) - end - - ## END OF THE METHODS TO PASS TO `sig`. - - # Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a - # wrapper that contains a proc that is evaluated to get the underlying type. This syntax however - # is needed for support by the static checker. - # - # @example - # NilableString = T.type_alias {T.nilable(String)} - # - # sig {params(arg: NilableString, default: String).returns(String)} - # def or_else(arg, default) - # arg || default - # end - # - # The name of the type alias is not preserved; Error messages will - # be printed with reference to the underlying type. - # - # TODO Remove `type` parameter. This was left in to make life easier while migrating. - def self.type_alias(type=nil, &blk) - if blk - T::Private::Types::TypeAlias.new(blk) - else - T::Utils.coerce(type) - end - end - - # References a type parameter which was previously defined with - # `type_parameters`. - # - # This is used for generic methods. - # - # @example - # sig - # .type_parameters(:U) - # .params( - # blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U)), - # ) - # .returns(T::Array[T.type_parameter(:U)]) - # def map(&blk); end - def self.type_parameter(name) - T::Types::TypeParameter.new(name) - end - - # Tells the typechecker that `value` is of type `type`. Use this to get additional checking after - # an expression that the typechecker is unable to analyze. If `checked` is true, raises an - # exception at runtime if the value doesn't match the type. - # - # Compared to `T.let`, `T.cast` is _trusted_ by static system. - def self.cast(value, type, checked: true) - return value unless checked - - Private::Casts.cast(value, type, cast_method: "T.cast") - end - - # Tells the typechecker to declare a variable of type `type`. Use - # like: - # - # seconds = T.let(0.0, Float) - # - # Compared to `T.cast`, `T.let` is _checked_ by static system. - # - # If `checked` is true, raises an exception at runtime if the value - # doesn't match the type. - def self.let(value, type, checked: true) - return value unless checked - - Private::Casts.cast(value, type, cast_method: "T.let") - end - - # Tells the type checker to treat `self` in the current block as `type`. - # Useful for blocks that are captured and executed later with instance_exec. - # Use like: - # - # seconds = lambda do - # T.bind(self, NewBinding) - # ... - # end - # - # `T.bind` behaves like `T.cast` in that it is assumed to be true statically. - # - # If `checked` is true, raises an exception at runtime if the value - # doesn't match the type (this is the default). - def self.bind(value, type, checked: true) - return value unless checked - - Private::Casts.cast(value, type, cast_method: "T.bind") - end - - # Tells the typechecker to ensure that `value` is of type `type` (if not, the typechecker will - # fail). Use this for debugging typechecking errors, or to ensure that type information is - # statically known and being checked appropriately. If `checked` is true, raises an exception at - # runtime if the value doesn't match the type. - def self.assert_type!(value, type, checked: true) - return value unless checked - - Private::Casts.cast(value, type, cast_method: "T.assert_type!") - end - - # For the static type checker, strips all type information from a value - # and returns the same value, but statically-typed as `T.untyped`. - # Can be used to tell the static checker to "trust you" by discarding type information - # you know to be incorrect. Use with care! - # (This has no effect at runtime.) - # - # We can't actually write this sig because we ourselves are inside - # the `T::` module and doing this would create a bootstrapping - # cycle. However, we also don't actually need to do so; An untyped - # identity method works just as well here. - # - # `sig {params(value: T.untyped).returns(T.untyped)}` - def self.unsafe(value) - value - end - - # A convenience method to `raise` when the argument is `nil` and return it - # otherwise. - # - # Intended to be used as: - # - # needs_foo(T.must(maybe_gives_foo)) - # - # Equivalent to: - # - # foo = maybe_gives_foo - # raise "nil" if foo.nil? - # needs_foo(foo) - # - # Intended to be used to promise sorbet that a given nilable value happens - # to contain a non-nil value at this point. - # - # `sig {params(arg: T.nilable(A)).returns(A)}` - def self.must(arg) - return arg if arg - return arg if arg == false - - begin - raise TypeError.new("Passed `nil` into T.must") - rescue TypeError => e # raise into rescue to ensure e.backtrace is populated - T::Configuration.inline_type_error_handler(e, {kind: 'T.must', value: arg, type: nil}) - end - end - - # A way to ask Sorbet to show what type it thinks an expression has. - # This can be useful for debugging and checking assumptions. - # In the runtime, merely returns the value passed in. - def self.reveal_type(value) - value - end - - # A way to ask Sorbet to prove that a certain branch of control flow never - # happens. Commonly used to assert that a case or if statement exhausts all - # possible cases. - def self.absurd(value) - msg = "Control flow reached T.absurd." - - case value - when Kernel - msg += " Got value: #{value}" - end - - begin - raise TypeError.new(msg) - rescue TypeError => e # raise into rescue to ensure e.backtrace is populated - T::Configuration.inline_type_error_handler(e, {kind: 'T.absurd', value: value, type: nil}) - end - end - - ### Generic classes ### - - module Array - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedArray::Untyped.new - else - T::Types::TypedArray.new(type) - end - end - end - - module Hash - def self.[](keys, values) - if keys.is_a?(T::Types::Untyped) && values.is_a?(T::Types::Untyped) - T::Types::TypedHash::Untyped.new - else - T::Types::TypedHash.new(keys: keys, values: values) - end - end - end - - module Enumerable - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedEnumerable::Untyped.new - else - T::Types::TypedEnumerable.new(type) - end - end - end - - module Enumerator - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedEnumerator::Untyped.new - else - T::Types::TypedEnumerator.new(type) - end - end - - module Lazy - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedEnumeratorLazy::Untyped.new - else - T::Types::TypedEnumeratorLazy.new(type) - end - end - end - end - - module Range - def self.[](type) - T::Types::TypedRange.new(type) - end - end - - module Set - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedSet::Untyped.new - else - T::Types::TypedSet.new(type) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb deleted file mode 100644 index 721bd4e0a7..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::AbstractUtils - Methods = T::Private::Methods - - # Returns whether a module is declared as abstract. After the module is finished being declared, - # this is equivalent to whether it has any abstract methods that haven't been implemented - # (because we validate that and raise an error otherwise). - # - # Note that checking `mod.is_a?(Abstract::Hooks)` is not a safe substitute for this method; when - # a class extends `Abstract::Hooks`, all of its subclasses, including the eventual concrete - # ones, will still have `Abstract::Hooks` as an ancestor. - def self.abstract_module?(mod) - !T::Private::Abstract::Data.get(mod, :abstract_type).nil? - end - - def self.abstract_method?(method) - signature = Methods.signature_for_method(method) - signature&.mode == Methods::Modes.abstract - end - - # Given a module, returns the set of methods declared as abstract (in itself or ancestors) - # that have not been implemented. - def self.abstract_methods_for(mod) - declared_methods = declared_abstract_methods_for(mod) - declared_methods.select do |declared_method| - actual_method = mod.instance_method(declared_method.name) - # Note that in the case where an abstract method is overridden by another abstract method, - # this method will return them both. This is intentional to ensure we validate the final - # implementation against all declarations of an abstract method (they might not all have the - # same signature). - abstract_method?(actual_method) - end - end - - # Given a module, returns the set of methods declared as abstract (in itself or ancestors) - # regardless of whether they have been implemented. - def self.declared_abstract_methods_for(mod) - methods = [] - mod.ancestors.each do |ancestor| - ancestor_methods = ancestor.private_instance_methods(false) + ancestor.instance_methods(false) - ancestor_methods.each do |method_name| - method = ancestor.instance_method(method_name) - methods << method if abstract_method?(method) - end - end - methods - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb deleted file mode 100644 index 8763d8707d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb +++ /dev/null @@ -1,8 +0,0 @@ -# typed: strict -# frozen_string_literal: true - -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)} -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb deleted file mode 100644 index 070b182aae..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb +++ /dev/null @@ -1,93 +0,0 @@ -# frozen_string_literal: true -# typed: ignore - -# Work around an interaction bug with sorbet-runtime and rspec-mocks, -# which occurs when using message expectations (*_any_instance_of, -# expect, allow) and and_call_original. -# -# When a sig is defined, sorbet-runtime will replace the sigged method -# with a wrapper that, upon first invocation, re-wraps the method with a faster -# implementation. -# -# When expect_any_instance_of is used, rspec stores a reference to the first wrapper, -# to be restored later. -# -# The first wrapper is invoked as part of the test and sorbet-runtime replaces -# the method definition with the second wrapper. -# -# But when mocks are cleaned up, rspec restores back to the first wrapper. -# Upon subsequent invocations, the first wrapper is called, and sorbet-runtime -# throws a runtime error, since this is an unexpected state. -# -# We work around this by forcing re-wrapping before rspec stores a reference -# to the method. -if defined? ::RSpec::Mocks - module T - module CompatibilityPatches - module RSpecCompatibility - module RecorderExtensions - def observe!(method_name) - method = @klass.instance_method(method_name.to_sym) - T::Private::Methods.maybe_run_sig_block_for_method(method) - super(method_name) - end - end - ::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions) if defined?(::RSpec::Mocks::AnyInstance::Recorder) - - module MethodDoubleExtensions - def initialize(object, method_name, proxy) - if ::Kernel.instance_method(:respond_to?).bind(object).call(method_name, true) - method = ::RSpec::Support.method_handle_for(object, method_name) - T::Private::Methods.maybe_run_sig_block_for_method(method) - end - super(object, method_name, proxy) - end - end - ::RSpec::Mocks::MethodDouble.prepend(MethodDoubleExtensions) if defined?(::RSpec::Mocks::MethodDouble) - end - end - end -end - -# Work around for sorbet-runtime wrapped methods. -# -# When a sig is defined, sorbet-runtime will replace the sigged method -# with a wrapper. Those wrapper methods look like `foo(*args, &blk)` -# so that wrappers can handle and pass on all the arguments supplied. -# -# However, that creates a problem with runtime reflection on the methods, -# since when a sigged method is introspected, it will always return its -# `arity` as `-1`, its `parameters` as `[[:rest, :args], [:block, :blk]]`, -# and its `source_location` as `[, ]`. -# -# This might be a problem for some applications that rely on getting the -# correct information from these methods. -# -# This compatibility module, when prepended to the `Method` class, would fix -# the return values of `arity`, `parameters` and `source_location`. -# -# @example -# require 'sorbet-runtime' -# ::Method.prepend(T::CompatibilityPatches::MethodExtensions) -module T - module CompatibilityPatches - module MethodExtensions - def arity - arity = super - return arity if arity != -1 || self.is_a?(Proc) - sig = T::Private::Methods.signature_for_method(self) - sig ? sig.method.arity : arity - end - - def source_location - sig = T::Private::Methods.signature_for_method(self) - sig ? sig.method.source_location : super - end - - def parameters - sig = T::Private::Methods.signature_for_method(self) - sig ? sig.method.parameters : super - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb deleted file mode 100644 index c012b6e8b6..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb +++ /dev/null @@ -1,591 +0,0 @@ -# typed: true -# frozen_string_literal: true - -module T::Configuration - # Cache this comparisonn to avoid two allocations all over the place. - AT_LEAST_RUBY_2_7 = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7') - - # Announces to Sorbet that we are currently in a test environment, so it - # should treat any sigs which are marked `.checked(:tests)` as if they were - # just a normal sig. - # - # If this method is not called, sigs marked `.checked(:tests)` will not be - # checked. In fact, such methods won't even be wrapped--the runtime will put - # back the original method. - # - # Note: Due to the way sigs are evaluated and methods are wrapped, this - # method MUST be called before any code calls `sig`. This method raises if - # it has been called too late. - def self.enable_checking_for_sigs_marked_checked_tests - T::Private::RuntimeLevels.enable_checking_in_tests - end - - # Announce to Sorbet that we would like the final checks to be enabled when - # including and extending modules. Iff this is not called, then the following - # example will not raise an error. - # - # ```ruby - # module M - # extend T::Sig - # sig(:final) {void} - # def foo; end - # end - # class C - # include M - # def foo; end - # end - # ``` - def self.enable_final_checks_on_hooks - T::Private::Methods.set_final_checks_on_hooks(true) - end - - # Undo the effects of a previous call to - # `enable_final_checks_on_hooks`. - def self.reset_final_checks_on_hooks - T::Private::Methods.set_final_checks_on_hooks(false) - end - - @include_value_in_type_errors = true - # Whether to include values in TypeError messages. - # - # Including values is useful for debugging, but can potentially leak - # sensitive information to logs. - # - # @return [T::Boolean] - def self.include_value_in_type_errors? - @include_value_in_type_errors - end - - # Configure if type errors excludes the value of the problematic type. - # - # The default is to include values in type errors: - # TypeError: Expected type Integer, got String with value "foo" - # - # When values are excluded from type errors: - # TypeError: Expected type Integer, got String - def self.exclude_value_in_type_errors - @include_value_in_type_errors = false - end - - # Opposite of exclude_value_in_type_errors. - # (Including values in type errors is the default) - def self.include_value_in_type_errors - @include_value_in_type_errors = true - end - - # Whether VM-defined prop serialization/deserialization routines can be enabled. - # - # @return [T::Boolean] - def self.can_enable_vm_prop_serde? - T::Props::Private::DeserializerGenerator.respond_to?(:generate2) - end - - @use_vm_prop_serde = false - # Whether to use VM-defined prop serialization/deserialization routines. - # - # The default is to use runtime codegen inside sorbet-runtime itself. - # - # @return [T::Boolean] - def self.use_vm_prop_serde? - @use_vm_prop_serde || false - end - - # Enable using VM-defined prop serialization/deserialization routines. - # - # This method is likely to break things outside of Stripe's systems. - def self.enable_vm_prop_serde - if !can_enable_vm_prop_serde? - hard_assert_handler('Ruby VM is not setup to use VM-defined prop serde') - end - @use_vm_prop_serde = true - end - - # Disable using VM-defined prop serialization/deserialization routines. - def self.disable_vm_prop_serde - @use_vm_prop_serde = false - end - - # Configure the default checked level for a sig with no explicit `.checked` - # builder. When unset, the default checked level is `:always`. - # - # Note: setting this option is potentially dangerous! Sorbet can't check all - # code statically. The runtime checks complement the checks that Sorbet does - # statically, so that methods don't have to guard themselves from being - # called incorrectly by untyped code. - # - # @param [:never, :compiled, :tests, :always] default_checked_level - def self.default_checked_level=(default_checked_level) - T::Private::RuntimeLevels.default_checked_level = default_checked_level - end - - @inline_type_error_handler = nil - # Set a handler to handle `TypeError`s raised by any in-line type assertions, - # including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`. - # - # By default, any `TypeError`s detected by this gem will be raised. Setting - # inline_type_error_handler to an object that implements :call (e.g. proc or - # lambda) allows users to customize the behavior when a `TypeError` is - # raised on any inline type assertion. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass - # nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [TypeError] error TypeError that was raised - # @param [Hash] opts A hash containing contextual information on the error: - # @option opts [String] :kind One of: - # ['T.cast', 'T.let', 'T.bind', 'T.assert_type!', 'T.must', 'T.absurd'] - # @option opts [Object, nil] :type Expected param/return value type - # @option opts [Object] :value Actual param/return value - # - # @example - # T::Configuration.inline_type_error_handler = lambda do |error, opts| - # puts error.message - # end - def self.inline_type_error_handler=(value) - validate_lambda_given!(value) - @inline_type_error_handler = value - end - - private_class_method def self.inline_type_error_handler_default(error, opts) - raise error - end - - def self.inline_type_error_handler(error, opts={}) - if @inline_type_error_handler - # Backwards compatibility before `inline_type_error_handler` took a second arg - if @inline_type_error_handler.arity == 1 - @inline_type_error_handler.call(error) - else - @inline_type_error_handler.call(error, opts) - end - else - inline_type_error_handler_default(error, opts) - end - nil - end - - @sig_builder_error_handler = nil - # Set a handler to handle errors that occur when the builder methods in the - # body of a sig are executed. The sig builder methods are inside a proc so - # that they can be lazily evaluated the first time the method being sig'd is - # called. - # - # By default, improper use of the builder methods within the body of a sig - # cause an ArgumentError to be raised. Setting sig_builder_error_handler to an - # object that implements :call (e.g. proc or lambda) allows users to - # customize the behavior when a sig can't be built for some reason. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass - # nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [StandardError] error The error that was raised - # @param [Thread::Backtrace::Location] location Location of the error - # - # @example - # T::Configuration.sig_builder_error_handler = lambda do |error, location| - # puts error.message - # end - def self.sig_builder_error_handler=(value) - validate_lambda_given!(value) - @sig_builder_error_handler = value - end - - private_class_method def self.sig_builder_error_handler_default(error, location) - raise ArgumentError.new("#{location.path}:#{location.lineno}: Error interpreting `sig`:\n #{error.message}\n\n") - end - - def self.sig_builder_error_handler(error, location) - if @sig_builder_error_handler - @sig_builder_error_handler.call(error, location) - else - sig_builder_error_handler_default(error, location) - end - nil - end - - @sig_validation_error_handler = nil - # Set a handler to handle sig validation errors. - # - # Sig validation errors include things like abstract checks, override checks, - # and type compatibility of arguments. They happen after a sig has been - # successfully built, but the built sig is incompatible with other sigs in - # some way. - # - # By default, sig validation errors cause an exception to be raised. - # Setting sig_validation_error_handler to an object that implements :call - # (e.g. proc or lambda) allows users to customize the behavior when a method - # signature's build fails. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass - # nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [StandardError] error The error that was raised - # @param [Hash] opts A hash containing contextual information on the error: - # @option opts [Method, UnboundMethod] :method Method on which the signature build failed - # @option opts [T::Private::Methods::Declaration] :declaration Method - # signature declaration struct - # @option opts [T::Private::Methods::Signature, nil] :signature Signature - # that failed (nil if sig build failed before Signature initialization) - # @option opts [T::Private::Methods::Signature, nil] :super_signature Super - # method's signature (nil if method is not an override or super method - # does not have a method signature) - # - # @example - # T::Configuration.sig_validation_error_handler = lambda do |error, opts| - # puts error.message - # end - def self.sig_validation_error_handler=(value) - validate_lambda_given!(value) - @sig_validation_error_handler = value - end - - private_class_method def self.sig_validation_error_handler_default(error, opts) - raise error - end - - def self.sig_validation_error_handler(error, opts={}) - if @sig_validation_error_handler - @sig_validation_error_handler.call(error, opts) - else - sig_validation_error_handler_default(error, opts) - end - nil - end - - @call_validation_error_handler = nil - # Set a handler for type errors that result from calling a method. - # - # By default, errors from calling a method cause an exception to be raised. - # Setting call_validation_error_handler to an object that implements :call - # (e.g. proc or lambda) allows users to customize the behavior when a method - # is called with invalid parameters, or returns an invalid value. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error - # report (pass nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [T::Private::Methods::Signature] signature Signature that failed - # @param [Hash] opts A hash containing contextual information on the error: - # @option opts [String] :message Error message - # @option opts [String] :kind One of: - # ['Parameter', 'Block parameter', 'Return value'] - # @option opts [Symbol] :name Param or block param name (nil for return - # value) - # @option opts [Object] :type Expected param/return value type - # @option opts [Object] :value Actual param/return value - # @option opts [Thread::Backtrace::Location] :location Location of the - # caller - # - # @example - # T::Configuration.call_validation_error_handler = lambda do |signature, opts| - # puts opts[:message] - # end - def self.call_validation_error_handler=(value) - validate_lambda_given!(value) - @call_validation_error_handler = value - end - - private_class_method def self.call_validation_error_handler_default(signature, opts) - raise TypeError.new(opts[:pretty_message]) - end - - def self.call_validation_error_handler(signature, opts={}) - if @call_validation_error_handler - @call_validation_error_handler.call(signature, opts) - else - call_validation_error_handler_default(signature, opts) - end - nil - end - - @log_info_handler = nil - # Set a handler for logging - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error - # report (pass nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [String] str Message to be logged - # @param [Hash] extra A hash containing additional parameters to be passed along to the logger. - # - # @example - # T::Configuration.log_info_handler = lambda do |str, extra| - # puts "#{str}, context: #{extra}" - # end - def self.log_info_handler=(value) - validate_lambda_given!(value) - @log_info_handler = value - end - - private_class_method def self.log_info_handler_default(str, extra) - puts "#{str}, extra: #{extra}" - end - - def self.log_info_handler(str, extra) - if @log_info_handler - @log_info_handler.call(str, extra) - else - log_info_handler_default(str, extra) - end - end - - @soft_assert_handler = nil - # Set a handler for soft assertions - # - # These generally shouldn't stop execution of the program, but rather inform - # some party of the assertion to action on later. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error - # report (pass nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [String] str Assertion message - # @param [Hash] extra A hash containing additional parameters to be passed along to the handler. - # - # @example - # T::Configuration.soft_assert_handler = lambda do |str, extra| - # puts "#{str}, context: #{extra}" - # end - def self.soft_assert_handler=(value) - validate_lambda_given!(value) - @soft_assert_handler = value - end - - private_class_method def self.soft_assert_handler_default(str, extra) - puts "#{str}, extra: #{extra}" - end - - def self.soft_assert_handler(str, extra) - if @soft_assert_handler - @soft_assert_handler.call(str, extra) - else - soft_assert_handler_default(str, extra) - end - end - - @hard_assert_handler = nil - # Set a handler for hard assertions - # - # These generally should stop execution of the program, and optionally inform - # some party of the assertion. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error - # report (pass nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [String] str Assertion message - # @param [Hash] extra A hash containing additional parameters to be passed along to the handler. - # - # @example - # T::Configuration.hard_assert_handler = lambda do |str, extra| - # raise "#{str}, context: #{extra}" - # end - def self.hard_assert_handler=(value) - validate_lambda_given!(value) - @hard_assert_handler = value - end - - private_class_method def self.hard_assert_handler_default(str, _) - raise str - end - - def self.hard_assert_handler(str, extra={}) - if @hard_assert_handler - @hard_assert_handler.call(str, extra) - else - hard_assert_handler_default(str, extra) - end - end - - @scalar_types = nil - # Set a list of class strings that are to be considered scalar. - # (pass nil to reset to default behavior) - # - # @param [String] values Class name. - # - # @example - # T::Configuration.scalar_types = ["NilClass", "TrueClass", "FalseClass", ...] - def self.scalar_types=(values) - if values.nil? - @scalar_types = values - else - 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 - end - end - - @default_scalar_types = { - "NilClass" => true, - "TrueClass" => true, - "FalseClass" => true, - "Integer" => true, - "Float" => true, - "String" => true, - "Symbol" => true, - "Time" => true, - "T::Enum" => true, - }.freeze - - def self.scalar_types - @scalar_types || @default_scalar_types - end - - # Guard against overrides of `name` or `to_s` - MODULE_NAME = Module.instance_method(:name) - private_constant :MODULE_NAME - - @default_module_name_mangler = if T::Configuration::AT_LEAST_RUBY_2_7 - ->(type) {MODULE_NAME.bind_call(type)} - else - ->(type) {MODULE_NAME.bind(type).call} - end - - @module_name_mangler = nil - - def self.module_name_mangler - @module_name_mangler || @default_module_name_mangler - end - - # Set to override the default behavior for converting types - # to names in generated code. Used by the runtime implementation - # associated with `--stripe-packages` mode. - # - # @param [Lambda, Proc, nil] handler Proc that converts a type (Class/Module) - # to a String (pass nil to reset to default behavior) - def self.module_name_mangler=(handler) - @module_name_mangler = handler - end - - @sensitivity_and_pii_handler = nil - # Set to a PII handler function. This will be called with the `sensitivity:` - # annotations on things that use `T::Props` and can modify them ahead-of-time. - # - # @param [Lambda, Proc, nil] handler Proc that takes a hash mapping symbols to the - # prop values. Pass nil to avoid changing `sensitivity:` annotations. - def self.normalize_sensitivity_and_pii_handler=(handler) - @sensitivity_and_pii_handler = handler - end - - def self.normalize_sensitivity_and_pii_handler - @sensitivity_and_pii_handler - end - - @redaction_handler = nil - # Set to a redaction handling function. This will be called when the - # `_redacted` version of a prop reader is used. By default this is set to - # `nil` and will raise an exception when the redacted version of a prop is - # accessed. - # - # @param [Lambda, Proc, nil] handler Proc that converts a value into its - # redacted version according to the spec passed as the second argument. - def self.redaction_handler=(handler) - @redaction_handler = handler - end - - def self.redaction_handler - @redaction_handler - end - - @class_owner_finder = nil - # Set to a function which can get the 'owner' of a class. This is - # used in reporting deserialization errors - # - # @param [Lambda, Proc, nil] handler Proc that takes a class and - # produces its owner, or `nil` if it does not have one. - def self.class_owner_finder=(handler) - @class_owner_finder = handler - end - - def self.class_owner_finder - @class_owner_finder - end - - # Temporarily disable ruby warnings while executing the given block. This is - # useful when doing something that would normally cause a warning to be - # emitted in Ruby verbose mode ($VERBOSE = true). - # - # @yield - # - def self.without_ruby_warnings - if $VERBOSE - begin - original_verbose = $VERBOSE - $VERBOSE = false - yield - ensure - $VERBOSE = original_verbose - end - else - yield - end - end - - @legacy_t_enum_migration_mode = false - def self.enable_legacy_t_enum_migration_mode - @legacy_t_enum_migration_mode = true - end - def self.disable_legacy_t_enum_migration_mode - @legacy_t_enum_migration_mode = false - end - def self.legacy_t_enum_migration_mode? - @legacy_t_enum_migration_mode || false - end - - @prop_freeze_handler = ->(instance, prop_name) {} - - def self.prop_freeze_handler=(handler) - @prop_freeze_handler = handler - end - - def self.prop_freeze_handler - @prop_freeze_handler - end - - @sealed_violation_whitelist = nil - # @param [Array] sealed_violation_whitelist An array of Regexp to validate - # whether inheriting /including a sealed module outside the defining module - # should be allowed. Useful to whitelist benign violations, like shim files - # generated for an autoloader. - def self.sealed_violation_whitelist=(sealed_violation_whitelist) - if !@sealed_violation_whitelist.nil? - raise ArgumentError.new("Cannot overwrite sealed_violation_whitelist after setting it") - end - - case sealed_violation_whitelist - when Array - sealed_violation_whitelist.each do |x| - case x - when Regexp then nil - else raise TypeError.new("sealed_violation_whitelist accepts an Array of Regexp") - end - end - else - raise TypeError.new("sealed_violation_whitelist= accepts an Array of Regexp") - end - - @sealed_violation_whitelist = sealed_violation_whitelist - end - def self.sealed_violation_whitelist - @sealed_violation_whitelist - end - - private_class_method def self.validate_lambda_given!(value) - if !value.nil? && !value.respond_to?(:call) - raise ArgumentError.new("Provided value must respond to :call") - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb deleted file mode 100644 index c2de09abaf..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb +++ /dev/null @@ -1,377 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -# Enumerations allow for type-safe declarations of a fixed set of values. -# -# Every value is a singleton instance of the class (i.e. `Suit::SPADE.is_a?(Suit) == true`). -# -# Each value has a corresponding serialized value. By default this is the constant's name converted -# to lowercase (e.g. `Suit::Club.serialize == 'club'`); however a custom value may be passed to the -# constructor. Enum will `freeze` the serialized value. -# -# @example Declaring an Enum: -# class Suit < T::Enum -# enums do -# CLUB = new -# SPADE = new -# DIAMOND = new -# HEART = new -# end -# end -# -# @example Custom serialization value: -# class Status < T::Enum -# enums do -# READY = new('rdy') -# ... -# end -# end -# -# @example Accessing values: -# Suit::SPADE -# -# @example Converting from serialized value to enum instance: -# Suit.deserialize('club') == Suit::CLUB -# -# @example Using enums in type signatures: -# sig {params(suit: Suit).returns(Boolean)} -# def is_red?(suit); ...; end -# -# WARNING: Enum instances are singletons that are shared among all their users. Their internals -# should be kept immutable to avoid unpredictable action at a distance. -class T::Enum - extend T::Sig - extend T::Props::CustomType - - # TODO(jez) Might want to restrict this, or make subclasses provide this type - SerializedVal = T.type_alias {T.untyped} - private_constant :SerializedVal - - ### Enum class methods ### - 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." \ - " Enums are not initialized until the 'enums do' block they are defined in has finished running." - end - @values - end - - # 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]))} - def self.each_value(&blk) - if blk - values.each(&blk) - else - values.each - end - end - - # Convert from serialized value to enum instance - # - # 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)} - def self.try_deserialize(serialized_val) - if @mapping.nil? - raise "Attempting to access serialization map of #{self.class} before it has been initialized." \ - " Enums are not initialized until the 'enums do' block they are defined in has finished running." - end - @mapping[serialized_val] - end - - # Convert from serialized value to enum instance. - # - # Note: It would have been nice to make this method final before people started overriding it. - # Note: Failed CriticalMethodsNoRuntimeTypingTest - # - # @return [self] - # @raise [KeyError] if serialized value does not match any instance. - 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? - raise KeyError.new("Enum #{self} key not found: #{serialized_val.inspect}") - end - res - end - - # 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)} - def self.has_serialized?(serialized_val) - if @mapping.nil? - raise "Attempting to access serialization map of #{self.class} before it has been initialized." \ - " Enums are not initialized until the 'enums do' block they are defined in has finished running." - end - @mapping.include?(serialized_val) - end - - # Note: Failed CriticalMethodsNoRuntimeTypingTest - 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 - # serialized, we throw the error on L102. - return nil if instance.nil? - - if self == T::Enum - raise "Cannot call T::Enum.serialize directly. You must call on a specific child class." - end - if instance.class != self - raise "Cannot call #serialize on a value that is not an instance of #{self}." - end - instance.serialize - end - - # Note: Failed CriticalMethodsNoRuntimeTypingTest - 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." - end - self.from_serialized(mongo_value) - end - - ### Enum instance methods ### - - sig {returns(T.self_type)} - def dup - self - end - - sig {returns(T.self_type).checked(:tests)} - def clone - self - end - - # Note: Failed CriticalMethodsNoRuntimeTypingTest - sig {returns(SerializedVal).checked(:never)} - def serialize - assert_bound! - @serialized_val - end - - 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)} - 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)} - def to_s - inspect - end - - sig {returns(String)} - def inspect - "#<#{self.class.name}::#{@const_name || '__UNINITIALIZED__'}>" - end - - sig {params(other: BasicObject).returns(T.nilable(Integer))} - def <=>(other) - case other - when self.class - self.serialize <=> other.serialize - else - nil - end - end - - # NB: Do not call this method. This exists to allow for a safe migration path in places where enum - # values are compared directly against string values. - # - # Ruby's string has a weird quirk where `'my_string' == obj` calls obj.==('my_string') if obj - # 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 - 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? - T::Configuration.soft_assert_handler( - msg, - storytime: {class: self.class.name}, - ) - serialize.to_s - else - raise NoMethodError.new(msg) - end - end - - sig {params(other: BasicObject).returns(T::Boolean).checked(:never)} - def ==(other) - case other - when String - if T::Configuration.legacy_t_enum_migration_mode? - comparison_assertion_failed(:==, other) - self.serialize == other - else - false - end - else - super(other) - end - end - - sig {params(other: BasicObject).returns(T::Boolean).checked(:never)} - def ===(other) - case other - when String - if T::Configuration.legacy_t_enum_migration_mode? - comparison_assertion_failed(:===, other) - self.serialize == other - else - false - end - else - super(other) - end - end - - 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', - storytime: { - class: self.class.name, - self: self.inspect, - other: other, - other_class: other.class.name, - method: method, - } - ) - end - - ### Private implementation ### - - sig {params(serialized_val: SerializedVal).void} - def initialize(serialized_val=nil) - raise 'T::Enum is abstract' if self.class == T::Enum - if !self.class.started_initializing? - raise "Must instantiate all enum values of #{self.class} inside 'enums do'." - end - if self.class.fully_initialized? - raise "Cannot instantiate a new enum value of #{self.class} after it has been initialized." - end - - serialized_val = serialized_val.frozen? ? serialized_val : serialized_val.dup.freeze - @serialized_val = T.let(serialized_val, T.nilable(SerializedVal)) - @const_name = T.let(nil, T.nilable(Symbol)) - self.class._register_instance(self) - end - - 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." \ - " Enums are not initialized until the 'enums do' block they are defined in has finished running." - end - end - - 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.nil? - freeze - end - - 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 - # least amount of repetition in migrated declarations. - -const_name.to_s.downcase.freeze - end - - sig {returns(T::Boolean)} - def self.started_initializing? - unless defined?(@started_initializing) - @started_initializing = T.let(false, T.nilable(T::Boolean)) - end - T.must(@started_initializing) - end - - sig {returns(T::Boolean)} - def self.fully_initialized? - unless defined?(@fully_initialized) - @fully_initialized = T.let(false, T.nilable(T::Boolean)) - end - T.must(@fully_initialized) - end - - # Maintains the order in which values are defined - sig {params(instance: T.untyped).void} - def self._register_instance(instance) - @values ||= [] - @values << T.cast(instance, T.attached_class) - end - - # 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} - 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? - raise "Enum #{self} is still initializing" if started_initializing? - - @started_initializing = true - - @values = T.let(nil, T.nilable(T::Array[T.attached_class])) - - yield - - @mapping = T.let(nil, T.nilable(T::Hash[SerializedVal, T.attached_class])) - @mapping = {} - - # Freeze the Enum class and bind the constant names into each of the instances. - self.constants(false).each do |const_name| - instance = self.const_get(const_name, false) - if !instance.is_a?(self) - raise "Invalid constant #{self}::#{const_name} on enum. " \ - "All constants defined for an enum must be instances itself (e.g. `Foo = new`)." - end - - instance._bind_name(const_name) - serialized = instance.serialize - if @mapping.include?(serialized) - raise "Enum values must have unique serializations. Value '#{serialized}' is repeated on #{self}." - end - @mapping[serialized] = instance - end - @values.freeze - @mapping.freeze - - 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')}}" - end - - @fully_initialized = true - end - - sig {params(child_class: Module).void} - def self.inherited(child_class) - super - - raise "Inheriting from children of T::Enum is prohibited" if self != T::Enum - end - - # Marshal support - sig {params(_level: Integer).returns(String)} - def _dump(_level) - Marshal.dump(serialize) - end - - sig {params(args: String).returns(T.attached_class)} - def self._load(args) - deserialize(Marshal.load(args)) # rubocop:disable Security/MarshalLoad - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb deleted file mode 100644 index 58def7aa1a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# Use as a mixin with extend (`extend T::Generic`). -module T::Generic - include T::Helpers - include Kernel - - ### Class/Module Helpers ### - - def [](*types) - self - end - - def type_member(variance=:invariant, &blk) - T::Types::TypeMember.new(variance) - end - - def type_template(variance=:invariant, &blk) - T::Types::TypeTemplate.new(variance) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb deleted file mode 100644 index 7f326e7384..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# Use as a mixin with extend (`extend T::Helpers`). -# Docs at https://sorbet.org/docs/ -module T::Helpers - extend T::Sig - - Private = T::Private - - ### Class/Module Helpers ### - - def abstract! - Private::Abstract::Declare.declare_abstract(self, type: :abstract) - end - - def interface! - Private::Abstract::Declare.declare_abstract(self, type: :interface) - end - - def final! - Private::Final.declare(self) - end - - def sealed! - Private::Sealed.declare(self, Kernel.caller(1..1)&.first&.split(':')&.first) - end - - # Causes a mixin to also mix in class methods from the named module. - # - # Nearly equivalent to - # - # def self.included(other) - # other.extend(mod) - # end - # - # Except that it is statically analyzed by sorbet. - def mixes_in_class_methods(mod, *mods) - Private::Mixins.declare_mixes_in_class_methods(self, [mod].concat(mods)) - end - - # Specify an inclusion or inheritance requirement for `self`. - # - # Example: - # - # module MyHelper - # extend T::Helpers - # - # requires_ancestor { Kernel } - # end - # - # class MyClass < BasicObject # error: `MyClass` must include `Kernel` (required by `MyHelper`) - # include MyHelper - # end - # - # TODO: implement the checks in sorbet-runtime. - def requires_ancestor(&block); end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb deleted file mode 100644 index 82998667f7..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb +++ /dev/null @@ -1,158 +0,0 @@ -# frozen_string_literal: true -# typed: false - -# Wraps an object, exposing only the methods defined on a given class/module. The idea is that, in -# the absence of a static type checker that would prevent you from calling non-Bar methods on a -# variable of type Bar, we can use these wrappers as a way of enforcing it at runtime. -# -# Once we ship static type checking, we should get rid of this entirely. -class T::InterfaceWrapper - extend T::Sig - - module Helpers - def wrap_instance(obj) - T::InterfaceWrapper.wrap_instance(obj, self) - end - - def wrap_instances(arr) - T::InterfaceWrapper.wrap_instances(arr, self) - end - end - - private_class_method :new # use `wrap_instance` - - def self.wrap_instance(obj, interface_mod) - wrapper = wrapped_dynamic_cast(obj, interface_mod) - if wrapper.nil? - raise "#{obj.class} cannot be cast to #{interface_mod}" - end - wrapper - end - - sig do - params( - arr: Array, - interface_mod: T.untyped - ) - .returns(Array) - end - def self.wrap_instances(arr, interface_mod) - arr.map {|instance| self.wrap_instance(instance, interface_mod)} - end - - def initialize(target_obj, interface_mod) - if target_obj.is_a?(T::InterfaceWrapper) - # wrapped_dynamic_cast should guarantee this never happens. - raise "Unexpected: wrapping a wrapper. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - - if !target_obj.is_a?(interface_mod) - # wrapped_dynamic_cast should guarantee this never happens. - raise "Unexpected: `is_a?` failed. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - - if target_obj.class == interface_mod - # wrapped_dynamic_cast should guarantee this never happens. - raise "Unexpected: exact class match. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - - @target_obj = target_obj - @interface_mod = interface_mod - self_methods = self.class.self_methods - - # If perf becomes an issue, we can define these on an anonymous subclass, and keep a cache - # so we only need to do it once per unique `interface_mod` - T::Utils.methods_excluding_object(interface_mod).each do |method_name| - if self_methods.include?(method_name) - raise "interface_mod has a method that conflicts with #{self.class}: #{method_name}" - end - - define_singleton_method(method_name) do |*args, &blk| - target_obj.send(method_name, *args, &blk) - end - - if target_obj.singleton_class.public_method_defined?(method_name) - # no-op, it's already public - elsif target_obj.singleton_class.protected_method_defined?(method_name) - singleton_class.send(:protected, method_name) - elsif target_obj.singleton_class.private_method_defined?(method_name) - singleton_class.send(:private, method_name) - else - raise "This should never happen. Report this bug at https://github.com/sorbet/sorbet/issues" - end - end - end - - def kind_of?(other) - is_a?(other) - end - - def is_a?(other) - if !other.is_a?(Module) - raise TypeError.new("class or module required") - end - - # This makes is_a? return true for T::InterfaceWrapper (and its ancestors), - # as well as for @interface_mod and its ancestors. - self.class <= other || @interface_mod <= other - end - - # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't - # want anyone else (besides dynamic_cast) calling it. - def __target_obj_DO_NOT_USE # rubocop:disable Naming/MethodName - @target_obj - end - - # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't - # want anyone else (besides wrapped_dynamic_cast) calling it. - def __interface_mod_DO_NOT_USE # rubocop:disable Naming/MethodName - @interface_mod - end - - # "Cast" an object to another type. If `obj` is an InterfaceWrapper, returns the the wrapped - # object if that matches `type`. Otherwise, returns `obj` if it matches `type`. Otherwise, - # returns nil. - # - # @param obj [Object] object to cast - # @param mod [Module] type to cast `obj` to - # - # @example - # if (impl = T::InterfaceWrapper.dynamic_cast(iface, MyImplementation)) - # impl.do_things - # end - def self.dynamic_cast(obj, mod) - if obj.is_a?(T::InterfaceWrapper) - target_obj = obj.__target_obj_DO_NOT_USE - target_obj.is_a?(mod) ? target_obj : nil - elsif obj.is_a?(mod) - obj - else - nil - end - end - - # Like dynamic_cast, but puts the result in its own wrapper if necessary. - # - # @param obj [Object] object to cast - # @param mod [Module] type to cast `obj` to - def self.wrapped_dynamic_cast(obj, mod) - # Avoid unwrapping and creating an equivalent wrapper. - if obj.is_a?(T::InterfaceWrapper) && obj.__interface_mod_DO_NOT_USE == mod - return obj - end - - cast_obj = dynamic_cast(obj, mod) - if cast_obj.nil? - nil - elsif cast_obj.class == mod - # Nothing to wrap, they want the full class - cast_obj - else - new(cast_obj, mod) - end - end - - def self.self_methods - @self_methods ||= self.instance_methods(false).to_set - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb deleted file mode 100644 index 96445357cb..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb +++ /dev/null @@ -1,65 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -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, package: T.nilable(String)).returns(T::Boolean)} - def self.non_forcing_is_a?(val, klass, package: nil) - method_name = "T::NonForcingConstants.non_forcing_is_a?" - if klass.empty? - raise ArgumentError.new("The string given to `#{method_name}` must not be empty") - end - - # We don't treat packages differently at runtime, but the static - # type-checker still needs to have the package and constant - # separated out. This just re-assembles the string as needed - if !package.nil? - klass = "::#{package}::#{klass}" - end - - current_klass = T.let(nil, T.nilable(Module)) - current_prefix = T.let(nil, T.nilable(String)) - - parts = klass.split('::') - parts.each do |part| - if current_klass.nil? - # First iteration - if part != "" && package.nil? - # if we've supplied a package, we're probably running in - # package mode, which means absolute references are - # meaningless - raise ArgumentError.new("The string given to `#{method_name}` must be an absolute constant reference that starts with `::`") - end - - current_klass = Object - current_prefix = '' - - # if this had a :: prefix, then there's no more loading to - # do---skip to the next one - next if part == "" - end - - if current_klass.autoload?(part) - # There's an autoload registered for that constant, which means it's not - # yet loaded. `value` can't be an instance of something not yet loaded. - return false - end - - # Sorbet guarantees that the string is an absolutely resolved name. - search_inheritance_chain = false - if !current_klass.const_defined?(part, search_inheritance_chain) - return false - end - - current_klass = current_klass.const_get(part) - current_prefix = "#{current_prefix}::#{part}" - - if !Module.===(current_klass) - raise ArgumentError.new("#{current_prefix} is not a class or module") - end - end - - current_klass.===(val) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb deleted file mode 100644 index 2692858ddf..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# We need to associate data with abstract modules. We could add instance methods to them that -# access ivars, but those methods will unnecessarily pollute the module namespace, and they'd -# have access to other private state and methods that they don't actually need. We also need to -# associate data with arbitrary classes/modules that implement abstract mixins, where we don't -# control the interface at all. So, we access data via these `get` and `set` methods. -# -# Using instance_variable_get/set here is gross, but the alternative is to use a hash keyed on -# `mod`, and we can't trust that arbitrary modules can be added to those, because there are lurky -# modules that override the `hash` method with something completely broken. -module T::Private::Abstract::Data - def self.get(mod, key) - mod.instance_variable_get("@opus_abstract__#{key}") if key?(mod, key) - end - - def self.set(mod, key, value) - mod.instance_variable_set("@opus_abstract__#{key}", value) - end - - def self.key?(mod, key) - mod.instance_variable_defined?("@opus_abstract__#{key}") - end - - # Works like `setdefault` in Python. If key has already been set, return its value. If not, - # insert `key` with a value of `default` and return `default`. - def self.set_default(mod, key, default) - if self.key?(mod, key) - self.get(mod, key) - else - self.set(mod, key, default) - default - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb deleted file mode 100644 index ce8ddf9531..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Abstract::Declare - Abstract = T::Private::Abstract - AbstractUtils = T::AbstractUtils - - def self.declare_abstract(mod, type:) - if AbstractUtils.abstract_module?(mod) - raise "#{mod} is already declared as abstract" - end - if T::Private::Final.final_module?(mod) - raise "#{mod} was already declared as final and cannot be declared as abstract" - end - - Abstract::Data.set(mod, :can_have_abstract_methods, true) - Abstract::Data.set(mod.singleton_class, :can_have_abstract_methods, true) - Abstract::Data.set(mod, :abstract_type, type) - - mod.extend(Abstract::Hooks) - mod.extend(T::InterfaceWrapper::Helpers) - - if mod.is_a?(Class) - if type == :interface - # Since `interface!` is just `abstract!` with some extra validation, we could technically - # allow this, but it's unclear there are good use cases, and it might be confusing. - raise "Classes can't be interfaces. Use `abstract!` instead of `interface!`." - end - - if mod.instance_method(:initialize).owner == mod - raise "You must call `abstract!` *before* defining an initialize method" - end - - # Don't need to silence warnings via without_ruby_warnings when calling - # define_method because of the guard above - - mod.send(:define_method, :initialize) do |*args, &blk| - if self.class == mod - raise "#{mod} is declared as abstract; it cannot be instantiated" - end - super(*args, &blk) - end - - # Ruby doesn not emit "method redefined" warnings for aliased methods - # (more robust than undef_method that would create a small window in which the method doesn't exist) - mod.send(:alias_method, :initialize, :initialize) - - if mod.respond_to?(:ruby2_keywords, true) - mod.send(:ruby2_keywords, :initialize) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb deleted file mode 100644 index fae9593ae8..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Abstract::Hooks - # This will become the self.extend_object method on a module that extends Abstract::Hooks. - # It gets called when *that* module gets extended in another class/module (similar to the - # `extended` hook, but this gets calls before the ancestors of `other` get modified, which - # is important for our validation). - private def extend_object(other) - T::Private::Abstract::Data.set(self, :last_used_by, other) - super - end - - # This will become the self.append_features method on a module that extends Abstract::Hooks. - # It gets called when *that* module gets included in another class/module (similar to the - # `included` hook, but this gets calls before the ancestors of `other` get modified, which - # is important for our validation). - private def append_features(other) - T::Private::Abstract::Data.set(self, :last_used_by, other) - super - end - - # This will become the self.inherited method on a class that extends Abstract::Hooks. - # It gets called when *that* class gets inherited by another class. - private def inherited(other) - super - # `self` may not actually be abstract -- it could be a concrete class that inherited from an - # abstract class. We only need to check this in `inherited` because, for modules being included - # or extended, the concrete ones won't have these hooks at all. This is just an optimization. - return if !T::AbstractUtils.abstract_module?(self) - - T::Private::Abstract::Data.set(self, :last_used_by, other) - end - - # This will become the self.prepended method on a module that extends Abstract::Hooks. - # It will get called when *that* module gets prepended in another class/module. - private def prepended(other) - # Prepending abstract methods is weird. You'd only be able to override them via other prepended - # modules, or in subclasses. Punt until we have a use case. - Kernel.raise "Prepending abstract mixins is not currently supported." - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb deleted file mode 100644 index ba0b57775c..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb +++ /dev/null @@ -1,128 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Abstract::Validate - Abstract = T::Private::Abstract - AbstractUtils = T::AbstractUtils - Methods = T::Private::Methods - SignatureValidation = T::Private::Methods::SignatureValidation - - def self.validate_abstract_module(mod) - type = Abstract::Data.get(mod, :abstract_type) - validate_interface(mod) if type == :interface - end - - # Validates a class/module with an abstract class/module as an ancestor. This must be called - # after all methods on `mod` have been defined. - def self.validate_subclass(mod) - can_have_abstract_methods = !T::Private::Abstract::Data.get(mod, :can_have_abstract_methods) - unimplemented_methods = [] - - T::AbstractUtils.declared_abstract_methods_for(mod).each do |abstract_method| - implementation_method = mod.instance_method(abstract_method.name) - if AbstractUtils.abstract_method?(implementation_method) - # Note that when we end up here, implementation_method might not be the same as - # abstract_method; the latter could've been overridden by another abstract method. In either - # case, if we have a concrete definition in an ancestor, that will end up as the effective - # implementation (see CallValidation.wrap_method_if_needed), so that's what we'll validate - # against. - implementation_method = T.unsafe(nil) - mod.ancestors.each do |ancestor| - if ancestor.instance_methods.include?(abstract_method.name) - method = ancestor.instance_method(abstract_method.name) - T::Private::Methods.maybe_run_sig_block_for_method(method) - if !T::AbstractUtils.abstract_method?(method) - implementation_method = method - break - end - end - end - if !implementation_method - # There's no implementation - if can_have_abstract_methods - unimplemented_methods << describe_method(abstract_method) - end - next # Nothing to validate - end - end - - implementation_signature = Methods.signature_for_method(implementation_method) - # When a signature exists and the method is defined directly on `mod`, we skip the validation - # here, because it will have already been done when the method was defined (by - # T::Private::Methods._on_method_added). - next if implementation_signature&.owner == mod - - # We validate the remaining cases here: (a) methods defined directly on `mod` without a - # signature and (b) methods from ancestors (note that these ancestors can come before or - # after the abstract module in the inheritance chain -- the former coming from - # walking `mod.ancestors` above). - abstract_signature = Methods.signature_for_method(abstract_method) - # We allow implementation methods to be defined without a signature. - # In that case, get its untyped signature. - implementation_signature ||= Methods::Signature.new_untyped( - method: implementation_method, - mode: Methods::Modes.override - ) - SignatureValidation.validate_override_shape(implementation_signature, abstract_signature) - SignatureValidation.validate_override_types(implementation_signature, abstract_signature) - end - - method_type = mod.singleton_class? ? "class" : "instance" - if !unimplemented_methods.empty? - raise "Missing implementation for abstract #{method_type} method(s) in #{mod}:\n" \ - "#{unimplemented_methods.join("\n")}\n" \ - "If #{mod} is meant to be an abstract class/module, you can call " \ - "`abstract!` or `interface!`. Otherwise, you must implement the method(s)." - end - end - - private_class_method def self.validate_interface_all_abstract(mod, method_names) - violations = method_names.map do |method_name| - method = mod.instance_method(method_name) - if !AbstractUtils.abstract_method?(method) - describe_method(method, show_owner: false) - end - end.compact - - if !violations.empty? - raise "`#{mod}` is declared as an interface, but the following methods are not declared " \ - "with `abstract`:\n#{violations.join("\n")}" - end - end - - private_class_method def self.validate_interface(mod) - interface_methods = T::Utils.methods_excluding_object(mod) - validate_interface_all_abstract(mod, interface_methods) - validate_interface_all_public(mod, interface_methods) - end - - private_class_method def self.validate_interface_all_public(mod, method_names) - violations = method_names.map do |method_name| - if !mod.public_method_defined?(method_name) - describe_method(mod.instance_method(method_name), show_owner: false) - end - end.compact - - if !violations.empty? - raise "All methods on an interface must be public. If you intend to have non-public " \ - "methods, declare your class/module using `abstract!` instead of `interface!`. " \ - "The following methods on `#{mod}` are not public: \n#{violations.join("\n")}" - end - end - - private_class_method def self.describe_method(method, show_owner: true) - loc = if method.source_location - method.source_location.join(':') - else - "" - end - - owner = if show_owner - " declared in #{method.owner}" - else - "" - end - - " * `#{method.name}`#{owner} at #{loc}" - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb deleted file mode 100644 index f771090814..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private - module Casts - def self.cast(value, type, cast_method:) - begin - error = T::Utils.coerce(type).error_message_for_obj(value) - return value unless error - - caller_loc = T.must(caller_locations(2..2)).first - - suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}" - - raise TypeError.new("#{cast_method}: #{error}\n#{suffix}") - rescue TypeError => e # raise into rescue to ensure e.backtrace is populated - T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type}) - value - end - end - - # there's a lot of shared logic with the above one, but factoring - # it out like this makes it easier to hopefully one day delete - # this one - def self.cast_recursive(value, type, cast_method:) - begin - error = T::Utils.coerce(type).error_message_for_obj_recursive(value) - return value unless error - - caller_loc = T.must(caller_locations(2..2)).first - - suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}" - - raise TypeError.new("#{cast_method}: #{error}\n#{suffix}") - rescue TypeError => e # raise into rescue to ensure e.backtrace is populated - T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type}) - value - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb deleted file mode 100644 index 269b70cbee..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb +++ /dev/null @@ -1,110 +0,0 @@ -# frozen_string_literal: true -# typed: false - -# Cut down version of Chalk::Tools::ClassUtils with only :replace_method functionality. -# Extracted to a separate namespace so the type system can be used standalone. -module T::Private::ClassUtils - class ReplacedMethod - def initialize(mod, old_method, new_method, overwritten, visibility) - if old_method.name != new_method.name - raise "Method names must match. old=#{old_method.name} new=#{new_method.name}" - end - @mod = mod - @old_method = old_method - @new_method = new_method - @overwritten = overwritten - @name = old_method.name - @visibility = visibility - @restored = false - end - - def restore - # The check below would also catch this, but this makes the failure mode much clearer - if @restored - raise "Method '#{@name}' on '#{@mod}' was already restored" - end - - if @mod.instance_method(@name) != @new_method - raise "Trying to restore #{@mod}##{@name} but the method has changed since the call to replace_method" - end - - @restored = true - - if @overwritten - # The original method was overwritten. Overwrite again to restore it. - T::Configuration.without_ruby_warnings do - @mod.send(:define_method, @old_method.name, @old_method) - end - else - # The original method was in an ancestor. Restore it by removing the overriding method. - @mod.send(:remove_method, @old_method.name) - end - - # Restore the visibility. Note that we need to do this even when we call remove_method - # above, because the module may have set custom visibility for a method it inherited. - @mod.send(@visibility, @old_method.name) - - nil - end - - def bind(obj) - @old_method.bind(obj) - end - - def to_s - @old_method.to_s - end - end - - # `name` must be an instance method (for class methods, pass in mod.singleton_class) - private_class_method def self.visibility_method_name(mod, name) - if mod.public_method_defined?(name) - :public - elsif mod.protected_method_defined?(name) - :protected - elsif mod.private_method_defined?(name) - :private - else - raise NameError.new("undefined method `#{name}` for `#{mod}`") - end - end - - # Replaces a method, either by overwriting it (if it is defined directly on `mod`) or by - # overriding it (if it is defined by one of mod's ancestors). Returns a ReplacedMethod instance - # on which you can call `bind(...).call(...)` to call the original method, or `restore` to - # restore the original method (by overwriting or removing the override). - def self.replace_method(mod, name, &blk) - original_method = mod.instance_method(name) - original_visibility = visibility_method_name(mod, name) - original_owner = original_method.owner - - mod.ancestors.each do |ancestor| - break if ancestor == mod - if ancestor == original_owner - # If we get here, that means the method we're trying to replace exists on a *prepended* - # mixin, which means in order to supersede it, we'd need to create a method on a new - # module that we'd prepend before `ancestor`. The problem with that approach is there'd - # be no way to remove that new module after prepending it, so we'd be left with these - # empty anonymous modules in the ancestor chain after calling `restore`. - # - # That's not necessarily a deal breaker, but for now, we're keeping it as unsupported. - raise "You're trying to replace `#{name}` on `#{mod}`, but that method exists in a " \ - "prepended module (#{ancestor}), which we don't currently support." - end - end - - overwritten = original_owner == mod - T::Configuration.without_ruby_warnings do - T::Private::DeclState.current.without_on_method_added do - mod.send(:define_method, name, &blk) - if blk.arity < 0 && mod.respond_to?(:ruby2_keywords, true) - mod.send(:ruby2_keywords, name) - end - end - end - mod.send(original_visibility, name) - new_method = mod.instance_method(name) - - ReplacedMethod.new(mod, original_method, new_method, overwritten, original_visibility) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb deleted file mode 100644 index fed86b40f3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private - module Compiler - # If this code ever runs, the caller is running interpreted (or the - # compiler didn't see the call to `running_compiled?` statically.) - # - # The Sorbet Compiler replaces calls to this method unconditionally (no - # runtime guards) to return `true` when compiling a file. - def self.running_compiled? - false - end - - # Returns `nil` because the compiler isn't running. - # - # The Sorbet Compiler replaces calls to this method unconditionally (no - # runtime guards) to return a String showing the Sorbet Compiler's version - # string. - def self.compiler_version - nil - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb deleted file mode 100644 index 8eeae57e4c..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -# typed: true - -class T::Private::DeclState - def self.current - Thread.current[:opus_types__decl_state] ||= self.new - end - - def self.current=(other) - Thread.current[:opus_types__decl_state] = other - end - - attr_accessor :active_declaration - attr_accessor :skip_on_method_added - - def reset! - self.active_declaration = nil - end - - def without_on_method_added - begin - # explicit 'self' is needed here - old_value = self.skip_on_method_added - self.skip_on_method_added = true - yield - ensure - self.skip_on_method_added = old_value - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb deleted file mode 100644 index 9ca747248e..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private::Final - module NoInherit - def inherited(arg) - super(arg) - raise "#{self} was declared as final and cannot be inherited" - end - end - - module NoIncludeExtend - def included(arg) - super(arg) - raise "#{self} was declared as final and cannot be included" - end - - def extended(arg) - super(arg) - raise "#{self} was declared as final and cannot be extended" - end - end - - def self.declare(mod) - if !mod.is_a?(Module) - raise "#{mod} is not a class or module and cannot be declared as final with `final!`" - end - if final_module?(mod) - raise "#{mod} was already declared as final and cannot be re-declared as final" - end - if T::AbstractUtils.abstract_module?(mod) - raise "#{mod} was already declared as abstract and cannot be declared as final" - end - if T::Private::Sealed.sealed_module?(mod) - raise "#{mod} was already declared as sealed and cannot be declared as final" - end - mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend) - mark_as_final_module(mod) - mark_as_final_module(mod.singleton_class) - T::Private::Methods.install_hooks(mod) - end - - def self.final_module?(mod) - mod.instance_variable_defined?(:@sorbet_final_module) - end - - private_class_method def self.mark_as_final_module(mod) - mod.instance_variable_set(:@sorbet_final_module, true) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb deleted file mode 100644 index 1720892a95..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb +++ /dev/null @@ -1,581 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private::Methods - @installed_hooks = {} - @signatures_by_method = {} - @sig_wrappers = {} - @sigs_that_raised = {} - # stores method names that were declared final without regard for where. - # enables early rejection of names that we know can't induce final method violations. - @was_ever_final_names = {} - # maps from a module's object_id to the set of final methods declared in that module. - # we also overload entries slightly: if the value is nil, that means that the - # module has final methods somewhere along its ancestor chain, but does not itself - # have any final methods. - # - # we need the latter information to know whether we need to check along the ancestor - # chain for final method violations. we need the former information because we - # care about exactly where a final method is defined (e.g. including the same module - # 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} - # 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. - @old_hooks = nil - - ARG_NOT_PROVIDED = Object.new - PROC_TYPE = Object.new - - DeclarationBlock = Struct.new(:mod, :loc, :blk, :final, :raw) - - def self.declare_sig(mod, loc, arg, &blk) - T::Private::DeclState.current.active_declaration = _declare_sig_internal(mod, loc, arg, &blk) - - nil - end - - # See tests for how to use this. But you shouldn't be using this. - def self._declare_sig(mod, arg=nil, &blk) - _declare_sig_internal(mod, caller_locations(1, 1).first, arg, raw: true, &blk) - end - - private_class_method def self._declare_sig_internal(mod, loc, arg, raw: false, &blk) - install_hooks(mod) - - if T::Private::DeclState.current.active_declaration - T::Private::DeclState.current.reset! - raise "You called sig twice without declaring a method in between" - end - - if !arg.nil? && arg != :final - raise "Invalid argument to `sig`: #{arg}" - end - - DeclarationBlock.new(mod, loc, blk, arg == :final, raw) - end - - def self._with_declared_signature(mod, declblock, &blk) - # If declblock is provided, this code is equivalent to the check in - # _declare_sig_internal, above. - # If declblock is not provided and we have an active declaration, we are - # obviously doing something wrong. - if T::Private::DeclState.current.active_declaration - T::Private::DeclState.current.reset! - raise "You called sig twice without declaring a method in between" - end - if declblock - T::Private::DeclState.current.active_declaration = declblock - end - mod.module_exec(&blk) - end - - def self.start_proc - DeclBuilder.new(PROC_TYPE, false) - end - - def self.finalize_proc(decl) - decl.finalized = true - - if decl.mode != Modes.standard - raise "Procs cannot have override/abstract modifiers" - end - if decl.mod != PROC_TYPE - raise "You are passing a DeclBuilder as a type. Did you accidentally use `self` inside a `sig` block?" - end - if decl.returns == ARG_NOT_PROVIDED - raise "Procs must specify a return type" - end - if decl.on_failure != ARG_NOT_PROVIDED - raise "Procs cannot use .on_failure" - end - - if decl.params == ARG_NOT_PROVIDED - decl.params = {} - end - - T::Types::Proc.new(decl.params, decl.returns) - end - - # Returns the signature for a method whose definition was preceded by `sig`. - # - # @param method [UnboundMethod] - # @return [T::Private::Methods::Signature] - def self.signature_for_method(method) - signature_for_key(method_to_key(method)) - end - - private_class_method def self.signature_for_key(key) - maybe_run_sig_block_for_key(key) - - # If a subclass Sub inherits a method `foo` from Base, then - # Sub.instance_method(:foo) != Base.instance_method(:foo) even though they resolve to the - # same method. Similarly, Foo.method(:bar) != Foo.singleton_class.instance_method(:bar). - # So, we always do the look up by the method on the owner (Base in this example). - @signatures_by_method[key] - end - - # when target includes a module with instance methods source_method_names, ensure there is zero intersection between - # the final instance methods of target and source_method_names. so, for every m in source_method_names, check if there - # is already a method defined on one of target_ancestors with the same name that is final. - # - # we assume that source_method_names has already been filtered to only include method - # names that were declared final at one point. - def self._check_final_ancestors(target, target_ancestors, source_method_names, source) - source_ancestors = nil - # use reverse_each to check farther-up ancestors first, for better error messages. - target_ancestors.reverse_each do |ancestor| - final_methods = @modules_with_final.fetch(ancestor.object_id, nil) - # In this case, either ancestor didn't have any final methods anywhere in its - # ancestor chain, or ancestor did have final methods somewhere in its ancestor - # chain, but no final methods defined in ancestor itself. Either way, there - # are no final methods to check here, so we can move on to the next ancestor. - next unless final_methods - source_method_names.each do |method_name| - next unless final_methods.include?(method_name) - - # If we get here, we are defining a method that some ancestor declared as - # final. however, we permit a final method to be defined multiple - # times if it is the same final method being defined each time. - if source - if !source_ancestors - source_ancestors = source.ancestors - # filter out things without actual final methods just to make sure that - # the below checks (which should be uncommon) go as quickly as possible. - source_ancestors.select! do |a| - @modules_with_final.fetch(a.object_id, nil) - end - end - # final-ness means that there should be no more than one index for which - # the below block returns true. - defining_ancestor_idx = source_ancestors.index do |a| - @modules_with_final.fetch(a.object_id).include?(method_name) - end - next if defining_ancestor_idx && source_ancestors[defining_ancestor_idx] == ancestor - end - - definition_file, definition_line = T::Private::Methods.signature_for_method(ancestor.instance_method(method_name)).method.source_location - is_redefined = target == ancestor - caller_loc = caller_locations&.find {|l| !l.to_s.match?(%r{sorbet-runtime[^/]*/lib/})} - extra_info = "\n" - if caller_loc - extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n" - end - - error_message = "The method `#{method_name}` on #{ancestor} was declared as final and cannot be " + - (is_redefined ? "redefined" : "overridden in #{target}") - pretty_message = "#{error_message}\n" \ - "Made final here: #{definition_file}:#{definition_line}\n" \ - "#{extra_info}" - - begin - raise pretty_message - rescue => e - # sig_validation_error_handler raises by default; on the off chance that - # it doesn't raise, we need to ensure that the rest of signature building - # sees a consistent state. This sig failed to validate, so we should get - # rid of it. If we don't do this, errors of the form "You called sig - # twice without declaring a method in between" will non-deterministically - # crop up in tests. - T::Private::DeclState.current.reset! - T::Configuration.sig_validation_error_handler(e, {}) - end - end - end - end - - def self.add_module_with_final_method(mod, method_name, is_singleton_method) - m = is_singleton_method ? mod.singleton_class : mod - mid = m.object_id - methods = @modules_with_final[mid] - if methods.nil? - methods = {} - @modules_with_final[mid] = methods - end - methods[method_name] = true - nil - end - - def self.note_module_deals_with_final(mod) - # Side-effectfully initialize the value if it's not already there - @modules_with_final[mod.object_id] - @modules_with_final[mod.singleton_class.object_id] - end - - # Only public because it needs to get called below inside the replace_method blocks below. - def self._on_method_added(hook_mod, method_name, is_singleton_method: false) - if T::Private::DeclState.current.skip_on_method_added - return - end - - current_declaration = T::Private::DeclState.current.active_declaration - mod = is_singleton_method ? hook_mod.singleton_class : hook_mod - - if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final) - raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final" - end - # Don't compute mod.ancestors if we don't need to bother checking final-ness. - if @was_ever_final_names.include?(method_name) && @modules_with_final.include?(mod.object_id) - _check_final_ancestors(mod, mod.ancestors, [method_name], nil) - # We need to fetch the active declaration again, as _check_final_ancestors - # may have reset it (see the comment in that method for details). - current_declaration = T::Private::DeclState.current.active_declaration - end - - if current_declaration.nil? - return - end - T::Private::DeclState.current.reset! - - if method_name == :method_added || method_name == :singleton_method_added - raise( - "Putting a `sig` on `#{method_name}` is not supported" \ - " (sorbet-runtime uses this method internally to perform `sig` validation logic)" - ) - end - - original_method = mod.instance_method(method_name) - sig_block = lambda do - T::Private::Methods.run_sig(hook_mod, method_name, original_method, current_declaration) - end - - # Always replace the original method with this wrapper, - # which is called only on the *first* invocation. - # This wrapper is very slow, so it will subsequently re-wrap with a much faster wrapper - # (or unwrap back to the original method). - key = method_owner_and_name_to_key(mod, method_name) - unless current_declaration.raw - T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk| - method_sig = T::Private::Methods.maybe_run_sig_block_for_key(key) - method_sig ||= T::Private::Methods._handle_missing_method_signature( - self, - original_method, - __callee__, - ) - - # Should be the same logic as CallValidation.wrap_method_if_needed but we - # don't want that extra layer of indirection in the callstack - if method_sig.mode == T::Private::Methods::Modes.abstract - # We're in an interface method, keep going up the chain - if defined?(super) - super(*args, &blk) - else - raise NotImplementedError.new("The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation.") - end - # Note, this logic is duplicated (intentionally, for micro-perf) at `CallValidation.wrap_method_if_needed`, - # make sure to keep changes in sync. - elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) - CallValidation.validate_call(self, original_method, method_sig, args, blk) - elsif T::Configuration::AT_LEAST_RUBY_2_7 - original_method.bind_call(self, *args, &blk) - else - original_method.bind(self).call(*args, &blk) - end - end - end - - @sig_wrappers[key] = sig_block - if current_declaration.final - @was_ever_final_names[method_name] = true - # use hook_mod, not mod, because for example, we want class C to be marked as having final if we def C.foo as - # final. change this to mod to see some final_method tests fail. - note_module_deals_with_final(hook_mod) - add_module_with_final_method(hook_mod, method_name, is_singleton_method) - end - end - - def self._handle_missing_method_signature(receiver, original_method, callee) - method_sig = T::Private::Methods.signature_for_method(original_method) - if !method_sig - raise "`sig` not present for method `#{callee}` on #{receiver.inspect} but you're trying to run it anyways. " \ - "This should only be executed if you used `alias_method` to grab a handle to a method after `sig`ing it, but that clearly isn't what you are doing. " \ - "Maybe look to see if an exception was thrown in your `sig` lambda or somehow else your `sig` wasn't actually applied to the method." - end - - if receiver.class <= original_method.owner - receiving_class = receiver.class - elsif receiver.singleton_class <= original_method.owner - receiving_class = receiver.singleton_class - elsif receiver.is_a?(Module) && receiver <= original_method.owner - receiving_class = receiver - else - raise "#{receiver} is not related to #{original_method} - how did we get here?" - end - - # Check for a case where `alias` or `alias_method` was called for a - # method which had already had a `sig` applied. In that case, we want - # to avoid hitting this slow path again, by moving to a faster validator - # just like we did or will for the original method. - # - # If this isn't an `alias` or `alias_method` case, we're probably in the - # middle of some metaprogramming using a Method object, e.g. a pattern like - # `arr.map(&method(:foo))`. There's nothing really we can do to optimize - # that here. - receiving_method = receiving_class.instance_method(callee) - if receiving_method != original_method && receiving_method.original_name == original_method.name - aliasing_mod = receiving_method.owner - method_sig = method_sig.as_alias(callee) - unwrap_method(aliasing_mod, method_sig, original_method) - end - - method_sig - end - - # Executes the `sig` block, and converts the resulting Declaration - # to a Signature. - def self.run_sig(hook_mod, method_name, original_method, declaration_block) - current_declaration = - begin - run_builder(declaration_block) - rescue DeclBuilder::BuilderError => e - T::Configuration.sig_builder_error_handler(e, declaration_block.loc) - nil - end - - signature = - if current_declaration - build_sig(hook_mod, method_name, original_method, current_declaration, declaration_block.loc) - else - Signature.new_untyped(method: original_method) - end - - unwrap_method(signature.method.owner, signature, original_method) - signature - end - - def self.run_builder(declaration_block) - builder = DeclBuilder.new(declaration_block.mod, declaration_block.raw) - builder - .instance_exec(&declaration_block.blk) - .finalize! - .decl - end - - def self.build_sig(hook_mod, method_name, original_method, current_declaration, loc) - begin - # We allow `sig` in the current module's context (normal case) and - if hook_mod != current_declaration.mod && - # inside `class << self`, and - hook_mod.singleton_class != current_declaration.mod && - # on `self` at the top level of a file - current_declaration.mod != TOP_SELF - raise "A method (#{method_name}) is being added on a different class/module (#{hook_mod}) than the " \ - "last call to `sig` (#{current_declaration.mod}). Make sure each call " \ - "to `sig` is immediately followed by a method definition on the same " \ - "class/module." - end - - signature = Signature.new( - method: original_method, - method_name: method_name, - raw_arg_types: current_declaration.params, - raw_return_type: current_declaration.returns, - bind: current_declaration.bind, - mode: current_declaration.mode, - check_level: current_declaration.checked, - on_failure: current_declaration.on_failure, - override_allow_incompatible: current_declaration.override_allow_incompatible, - defined_raw: current_declaration.raw, - ) - - SignatureValidation.validate(signature) - signature - rescue => e - super_method = original_method&.super_method - super_signature = signature_for_method(super_method) if super_method - - T::Configuration.sig_validation_error_handler( - e, - method: original_method, - declaration: current_declaration, - signature: signature, - super_signature: super_signature - ) - - Signature.new_untyped(method: original_method) - end - end - - def self.unwrap_method(mod, signature, original_method) - maybe_wrapped_method = CallValidation.wrap_method_if_needed(mod, signature, original_method) - @signatures_by_method[method_to_key(maybe_wrapped_method)] = signature - end - - def self.has_sig_block_for_method(method) - has_sig_block_for_key(method_to_key(method)) - end - - private_class_method def self.has_sig_block_for_key(key) - @sig_wrappers.key?(key) - end - - def self.maybe_run_sig_block_for_method(method) - maybe_run_sig_block_for_key(method_to_key(method)) - end - - # Only public so that it can be accessed in the closure for _on_method_added - def self.maybe_run_sig_block_for_key(key) - run_sig_block_for_key(key) if has_sig_block_for_key(key) - end - - def self.run_sig_block_for_method(method) - run_sig_block_for_key(method_to_key(method)) - end - - private_class_method def self.run_sig_block_for_key(key) - blk = @sig_wrappers[key] - if !blk - sig = @signatures_by_method[key] - if sig - # We already ran the sig block, perhaps in another thread. - return sig - else - raise "No `sig` wrapper for #{key_to_method(key)}" - end - end - - begin - sig = blk.call - rescue - @sigs_that_raised[key] = true - raise - end - if @sigs_that_raised[key] - raise "A previous invocation of #{key_to_method(key)} raised, and the current one succeeded. Please don't do that." - end - - @sig_wrappers.delete(key) - sig - end - - def self.run_all_sig_blocks - loop do - break if @sig_wrappers.empty? - key, = @sig_wrappers.first - run_sig_block_for_key(key) - end - end - - def self.all_checked_tests_sigs - @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 - # methods M on source, M is not defined on any of target's ancestors. - def self._hook_impl(target, singleton_class, source) - # we do not need to call add_was_ever_final here, because we have already marked - # any such methods when source was originally defined. - if !@modules_with_final.include?(target.object_id) - if !@modules_with_final.include?(source.object_id) - return - end - note_module_deals_with_final(target) - install_hooks(target) - return - end - - methods = source.instance_methods - methods.select! do |method_name| - @was_ever_final_names.include?(method_name) - end - if methods.empty? - return - end - - target_ancestors = singleton_class ? target.singleton_class.ancestors : target.ancestors - _check_final_ancestors(target, target_ancestors, methods, source) - end - - def self.set_final_checks_on_hooks(enable) - is_enabled = !@old_hooks.nil? - if enable == is_enabled - return - end - if is_enabled - @old_hooks.each(&:restore) - @old_hooks = nil - else - old_included = T::Private::ClassUtils.replace_method(Module, :included) do |arg| - old_included.bind(self).call(arg) - ::T::Private::Methods._hook_impl(arg, false, self) - end - old_extended = T::Private::ClassUtils.replace_method(Module, :extended) do |arg| - old_extended.bind(self).call(arg) - ::T::Private::Methods._hook_impl(arg, true, self) - end - old_inherited = T::Private::ClassUtils.replace_method(Class, :inherited) do |arg| - old_inherited.bind(self).call(arg) - ::T::Private::Methods._hook_impl(arg, false, self) - end - @old_hooks = [old_included, old_extended, old_inherited] - end - end - - module MethodHooks - def method_added(name) - super(name) - ::T::Private::Methods._on_method_added(self, name, is_singleton_method: false) - end - end - - module SingletonMethodHooks - def singleton_method_added(name) - super(name) - ::T::Private::Methods._on_method_added(self, name, is_singleton_method: true) - end - end - - def self.install_hooks(mod) - return if @installed_hooks.include?(mod) - @installed_hooks[mod] = true - - if mod == TOP_SELF - # self at the top-level of a file is weirdly special in Ruby - # The Ruby VM on startup creates an `Object.new` and stashes it. - # Unlike when we're using sig inside a module, `self` is actually a - # normal object, not an instance of Module. - # - # Thus we can't ask things like mod.singleton_class? (since that's - # defined only on Module, not on Object) and even if we could, the places - # where we need to install the hooks are special. - mod.extend(SingletonMethodHooks) # def self.foo; end (at top level) - Object.extend(MethodHooks) # def foo; end (at top level) - return - end - - # See https://github.com/sorbet/sorbet/pull/3964 for an explanation of why this - # check (which theoretically should not be needed) is actually needed. - if !mod.is_a?(Module) - return - end - - if mod.singleton_class? - mod.include(SingletonMethodHooks) - else - mod.extend(MethodHooks) - end - mod.extend(SingletonMethodHooks) - 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}" - end - - private_class_method def self.method_to_key(method) - method_owner_and_name_to_key(method.owner, method.name) - end - - private_class_method def self.key_to_method(key) - id, name = key.split("#") - obj = ObjectSpace._id2ref(id.to_i) - obj.instance_method(name) - end -end - -# This has to be here, and can't be nested inside `T::Private::Methods`, -# because the value of `self` depends on lexical (nesting) scope, and we -# specifically need a reference to the file-level self, i.e. `main:Object` -T::Private::Methods::TOP_SELF = self diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb deleted file mode 100644 index 1889daa991..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb +++ /dev/null @@ -1,221 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private::Methods::CallValidation - CallValidation = T::Private::Methods::CallValidation - Modes = T::Private::Methods::Modes - - # Wraps a method with a layer of validation for the given type signature. - # This wrapper is meant to be fast, and is applied by a previous wrapper, - # which was placed by `_on_method_added`. - # - # @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) - if method_sig.mode == T::Private::Methods::Modes.abstract - T::Private::ClassUtils.replace_method(mod, method_sig.method_name) do |*args, &blk| - # TODO: write a cop to ensure that abstract methods have an empty body - # - # We allow abstract methods to be implemented by things further down the ancestor chain. - # So, if a super method exists, call it. - if defined?(super) - super(*args, &blk) - else - raise NotImplementedError.new( - "The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation." - ) - end - end - # Do nothing in this case; this method was not wrapped in _on_method_added. - elsif method_sig.defined_raw - # Note, this logic is duplicated (intentionally, for micro-perf) at `Methods._on_method_added`, - # make sure to keep changes in sync. - # This is a trapdoor point for each method: - # if a given method is wrapped, it stays wrapped; and if not, it's never wrapped. - # (Therefore, we need the `@wrapped_tests_with_validation` check in `T::RuntimeLevels`.) - elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) - create_validator_method(mod, original_method, method_sig, original_visibility) - else - T::Configuration.without_ruby_warnings do - # get all the shims out of the way and put back the original method - T::Private::DeclState.current.without_on_method_added do - mod.send(:define_method, method_sig.method_name, original_method) - end - mod.send(original_visibility, method_sig.method_name) - end - end - # Return the newly created method (or the original one if we didn't replace it) - mod.instance_method(method_sig.method_name) - end - - @is_allowed_to_have_fast_path = true - def self.is_allowed_to_have_fast_path - @is_allowed_to_have_fast_path - end - - def self.disable_fast_path - @is_allowed_to_have_fast_path = false - end - - 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} - ok_for_fast_path = has_fixed_arity && !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)} - 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) - - T::Configuration.without_ruby_warnings do - T::Private::DeclState.current.without_on_method_added do - if simple_method - create_validator_method_fast(mod, original_method, method_sig) - elsif simple_procedure - create_validator_procedure_fast(mod, original_method, method_sig) - elsif ok_for_fast_path && method_sig.return_type.is_a?(T::Private::Types::Void) - create_validator_procedure_medium(mod, original_method, method_sig) - elsif ok_for_fast_path - create_validator_method_medium(mod, original_method, method_sig) - else - create_validator_slow(mod, original_method, method_sig) - end - end - end - mod.send(original_visibility, method_sig.method_name) - end - - def self.create_validator_slow(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |*args, &blk| - CallValidation.validate_call(self, original_method, method_sig, args, blk) - end - if mod.respond_to?(:ruby2_keywords, true) - mod.send(:ruby2_keywords, method_sig.method_name) - end - end - - def self.validate_call(instance, original_method, method_sig, args, blk) - # This method is called for every `sig`. It's critical to keep it fast and - # reduce number of allocations that happen here. - - if method_sig.bind - message = method_sig.bind.error_message_for_obj(instance) - if message - CallValidation.report_error( - method_sig, - message, - 'Bind', - nil, - method_sig.bind, - instance - ) - end - end - - # NOTE: We don't bother validating for missing or extra kwargs; - # the method call itself will take care of that. - method_sig.each_args_value_type(args) do |name, arg, type| - message = type.error_message_for_obj(arg) - if message - CallValidation.report_error( - method_sig, - message, - 'Parameter', - name, - type, - arg, - caller_offset: 2 - ) - end - end - - if method_sig.block_type - message = method_sig.block_type.error_message_for_obj(blk) - if message - CallValidation.report_error( - method_sig, - message, - 'Block parameter', - method_sig.block_name, - method_sig.block_type, - blk - ) - end - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = T::Configuration::AT_LEAST_RUBY_2_7 ? original_method.bind_call(instance, *args, &blk) : original_method.bind(instance).call(*args, &blk) - - # The only type that is allowed to change the return value is `.void`. - # It ignores what you returned and changes it to be a private singleton. - if method_sig.return_type.is_a?(T::Private::Types::Void) - T::Private::Types::Void::VOID - else - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - ) - end - return_value - end - end - - def self.report_error(method_sig, error_message, kind, name, type, value, caller_offset: 0) - caller_loc = T.must(caller_locations(3 + caller_offset, 1))[0] - definition_file, definition_line = method_sig.method.source_location - - pretty_message = "#{kind}#{name ? " '#{name}'" : ''}: #{error_message}\n" \ - "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" \ - "Definition: #{definition_file}:#{definition_line}" - - T::Configuration.call_validation_error_handler( - method_sig, - message: error_message, - pretty_message: pretty_message, - kind: kind, - name: name, - type: type, - value: value, - 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 - raise NameError.new("undefined method `#{name}` for `#{mod}`") - end - end -end - -if T::Configuration::AT_LEAST_RUBY_2_7 - require_relative './call_validation_2_7' -else - require_relative './call_validation_2_6' -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb deleted file mode 100644 index 753580dc36..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb +++ /dev/null @@ -1,1203 +0,0 @@ -# frozen_string_literal: true -# typed: false - -# DO NOT EDIT. This file is autogenerated. To regenerate, run: -# -# bazel test //gems/sorbet-runtime:update_call_validation - -module T::Private::Methods::CallValidation - def self.create_validator_method_fast(mod, original_method, method_sig) - if method_sig.return_type.is_a?(T::Private::Types::Void) - raise 'Should have used create_validator_procedure_fast' - end - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type) - elsif method_sig.arg_types.length == 1 - create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type) - elsif method_sig.arg_types.length == 2 - create_validator_method_fast2(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type) - elsif method_sig.arg_types.length == 3 - create_validator_method_fast3(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type) - elsif method_sig.arg_types.length == 4 - create_validator_method_fast4(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type, - method_sig.arg_types[3][1].raw_type) - else - raise 'should not happen' - end - end - - def self.create_validator_method_fast0(mod, original_method, method_sig, return_type) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(&blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast1(mod, original_method, method_sig, return_type, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, arg2, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3.is_a?(arg3_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_procedure_fast(mod, original_method, method_sig) - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_procedure_fast0(mod, original_method, method_sig) - elsif method_sig.arg_types.length == 1 - create_validator_procedure_fast1(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type) - elsif method_sig.arg_types.length == 2 - create_validator_procedure_fast2(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type) - elsif method_sig.arg_types.length == 3 - create_validator_procedure_fast3(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type) - elsif method_sig.arg_types.length == 4 - create_validator_procedure_fast4(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type, - method_sig.arg_types[3][1].raw_type) - else - raise 'should not happen' - end - end - - def self.create_validator_procedure_fast0(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(&blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast1(mod, original_method, method_sig, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast2(mod, original_method, method_sig, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, arg2, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3.is_a?(arg3_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_method_medium(mod, original_method, method_sig) - if method_sig.return_type.is_a?(T::Private::Types::Void) - raise 'Should have used create_validator_procedure_medium' - end - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_method_medium0(mod, original_method, method_sig, method_sig.return_type) - elsif method_sig.arg_types.length == 1 - create_validator_method_medium1(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1]) - elsif method_sig.arg_types.length == 2 - create_validator_method_medium2(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1]) - elsif method_sig.arg_types.length == 3 - create_validator_method_medium3(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1]) - elsif method_sig.arg_types.length == 4 - create_validator_method_medium4(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1], - method_sig.arg_types[3][1]) - else - raise 'should not happen' - end - end - - def self.create_validator_method_medium0(mod, original_method, method_sig, return_type) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(&blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium1(mod, original_method, method_sig, return_type, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, arg2, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3_type.valid?(arg3) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_procedure_medium(mod, original_method, method_sig) - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_procedure_medium0(mod, original_method, method_sig) - elsif method_sig.arg_types.length == 1 - create_validator_procedure_medium1(mod, original_method, method_sig, - method_sig.arg_types[0][1]) - elsif method_sig.arg_types.length == 2 - create_validator_procedure_medium2(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1]) - elsif method_sig.arg_types.length == 3 - create_validator_procedure_medium3(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1]) - elsif method_sig.arg_types.length == 4 - create_validator_procedure_medium4(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1], - method_sig.arg_types[3][1]) - else - raise 'should not happen' - end - end - - def self.create_validator_procedure_medium0(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(&blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium1(mod, original_method, method_sig, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium2(mod, original_method, method_sig, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, arg2, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3_type.valid?(arg3) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) - T::Private::Types::Void::VOID - end - end - -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb deleted file mode 100644 index 1686db8977..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb +++ /dev/null @@ -1,1203 +0,0 @@ -# frozen_string_literal: true -# typed: false - -# DO NOT EDIT. This file is autogenerated. To regenerate, run: -# -# bazel test //gems/sorbet-runtime:update_call_validation - -module T::Private::Methods::CallValidation - def self.create_validator_method_fast(mod, original_method, method_sig) - if method_sig.return_type.is_a?(T::Private::Types::Void) - raise 'Should have used create_validator_procedure_fast' - end - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type) - elsif method_sig.arg_types.length == 1 - create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type) - elsif method_sig.arg_types.length == 2 - create_validator_method_fast2(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type) - elsif method_sig.arg_types.length == 3 - create_validator_method_fast3(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type) - elsif method_sig.arg_types.length == 4 - create_validator_method_fast4(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type, - method_sig.arg_types[3][1].raw_type) - else - raise 'should not happen' - end - end - - def self.create_validator_method_fast0(mod, original_method, method_sig, return_type) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast1(mod, original_method, method_sig, return_type, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3.is_a?(arg3_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_procedure_fast(mod, original_method, method_sig) - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_procedure_fast0(mod, original_method, method_sig) - elsif method_sig.arg_types.length == 1 - create_validator_procedure_fast1(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type) - elsif method_sig.arg_types.length == 2 - create_validator_procedure_fast2(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type) - elsif method_sig.arg_types.length == 3 - create_validator_procedure_fast3(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type) - elsif method_sig.arg_types.length == 4 - create_validator_procedure_fast4(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type, - method_sig.arg_types[3][1].raw_type) - else - raise 'should not happen' - end - end - - def self.create_validator_procedure_fast0(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast1(mod, original_method, method_sig, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast2(mod, original_method, method_sig, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, arg2, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3.is_a?(arg3_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_method_medium(mod, original_method, method_sig) - if method_sig.return_type.is_a?(T::Private::Types::Void) - raise 'Should have used create_validator_procedure_medium' - end - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_method_medium0(mod, original_method, method_sig, method_sig.return_type) - elsif method_sig.arg_types.length == 1 - create_validator_method_medium1(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1]) - elsif method_sig.arg_types.length == 2 - create_validator_method_medium2(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1]) - elsif method_sig.arg_types.length == 3 - create_validator_method_medium3(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1]) - elsif method_sig.arg_types.length == 4 - create_validator_method_medium4(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1], - method_sig.arg_types[3][1]) - else - raise 'should not happen' - end - end - - def self.create_validator_method_medium0(mod, original_method, method_sig, return_type) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium1(mod, original_method, method_sig, return_type, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3_type.valid?(arg3) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_procedure_medium(mod, original_method, method_sig) - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_procedure_medium0(mod, original_method, method_sig) - elsif method_sig.arg_types.length == 1 - create_validator_procedure_medium1(mod, original_method, method_sig, - method_sig.arg_types[0][1]) - elsif method_sig.arg_types.length == 2 - create_validator_procedure_medium2(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1]) - elsif method_sig.arg_types.length == 3 - create_validator_procedure_medium3(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1]) - elsif method_sig.arg_types.length == 4 - create_validator_procedure_medium4(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1], - method_sig.arg_types[3][1]) - else - raise 'should not happen' - end - end - - def self.create_validator_procedure_medium0(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium1(mod, original_method, method_sig, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium2(mod, original_method, method_sig, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, arg2, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3_type.valid?(arg3) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) - T::Private::Types::Void::VOID - end - end - -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb deleted file mode 100644 index b48b1d5b68..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb +++ /dev/null @@ -1,232 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Methods - Declaration = Struct.new(:mod, :params, :returns, :bind, :mode, :checked, :finalized, :on_failure, :override_allow_incompatible, :type_parameters, :raw) - - class DeclBuilder - attr_reader :decl - - class BuilderError < StandardError; end - - private def check_live! - if decl.finalized - raise BuilderError.new("You can't modify a signature declaration after it has been used.") - end - end - - def initialize(mod, raw) - # TODO RUBYPLAT-1278 - with ruby 2.5, use kwargs here - @decl = Declaration.new( - mod, - ARG_NOT_PROVIDED, # params - ARG_NOT_PROVIDED, # returns - ARG_NOT_PROVIDED, # bind - Modes.standard, # mode - ARG_NOT_PROVIDED, # checked - false, # finalized - ARG_NOT_PROVIDED, # on_failure - nil, # override_allow_incompatible - ARG_NOT_PROVIDED, # type_parameters - raw - ) - end - - def params(**params) - check_live! - if !decl.params.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .params twice") - end - - if params.empty? - raise BuilderError.new("params expects keyword arguments") - end - decl.params = params - - self - end - - def returns(type) - check_live! - if decl.returns.is_a?(T::Private::Types::Void) - raise BuilderError.new("You can't call .returns after calling .void.") - end - if !decl.returns.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .returns multiple times in a signature.") - end - - decl.returns = type - - self - end - - def void - check_live! - if !decl.returns.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .void after calling .returns.") - end - - decl.returns = T::Private::Types::Void.new - - self - end - - def bind(type) - check_live! - if !decl.bind.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .bind multiple times in a signature.") - end - - decl.bind = type - - self - end - - def checked(level) - check_live! - - if !decl.checked.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .checked multiple times in a signature.") - end - if (level == :never || level == :compiled) && !decl.on_failure.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't use .checked(:#{level}) with .on_failure because .on_failure will have no effect.") - end - if !T::Private::RuntimeLevels::LEVELS.include?(level) - raise BuilderError.new("Invalid `checked` level '#{level}'. Use one of: #{T::Private::RuntimeLevels::LEVELS}.") - end - - decl.checked = level - - self - end - - def on_failure(*args) - check_live! - - if !decl.on_failure.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .on_failure multiple times in a signature.") - end - if decl.checked == :never || decl.checked == :compiled - raise BuilderError.new("You can't use .on_failure with .checked(:#{decl.checked}) because .on_failure will have no effect.") - end - - decl.on_failure = args - - self - end - - def abstract - check_live! - - case decl.mode - when Modes.standard - decl.mode = Modes.abstract - when Modes.abstract - raise BuilderError.new(".abstract cannot be repeated in a single signature") - else - raise BuilderError.new("`.abstract` cannot be combined with `.override` or `.overridable`.") - end - - self - end - - def final - check_live! - raise BuilderError.new("The syntax for declaring a method final is `sig(:final) {...}`, not `sig {final. ...}`") - end - - def override(allow_incompatible: false) - check_live! - - case decl.mode - when Modes.standard - decl.mode = Modes.override - decl.override_allow_incompatible = allow_incompatible - when Modes.override, Modes.overridable_override - raise BuilderError.new(".override cannot be repeated in a single signature") - when Modes.overridable - decl.mode = Modes.overridable_override - else - raise BuilderError.new("`.override` cannot be combined with `.abstract`.") - end - - self - end - - def overridable - check_live! - - case decl.mode - when Modes.abstract - raise BuilderError.new("`.overridable` cannot be combined with `.#{decl.mode}`") - when Modes.override - decl.mode = Modes.overridable_override - when Modes.standard - decl.mode = Modes.overridable - when Modes.overridable, Modes.overridable_override - raise BuilderError.new(".overridable cannot be repeated in a single signature") - end - - self - end - - # Declares valid type paramaters which can be used with `T.type_parameter` in - # this `sig`. - # - # This is used for generic methods. Example usage: - # - # sig do - # type_parameters(:U) - # .params(blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U))) - # .returns(T::Array[T.type_parameter(:U)]) - # end - # def map(&blk); end - def type_parameters(*names) - check_live! - - names.each do |name| - raise BuilderError.new("not a symbol: #{name}") unless name.is_a?(Symbol) - end - - if !decl.type_parameters.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .type_parameters multiple times in a signature.") - end - - decl.type_parameters = names - - self - end - - def finalize! - check_live! - - if decl.returns.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You must provide a return type; use the `.returns` or `.void` builder methods.") - end - - if decl.bind.equal?(ARG_NOT_PROVIDED) - decl.bind = nil - end - if decl.checked.equal?(ARG_NOT_PROVIDED) - default_checked_level = T::Private::RuntimeLevels.default_checked_level - if (default_checked_level == :never || default_checked_level == :compiled) && !decl.on_failure.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("To use .on_failure you must additionally call .checked(:tests) or .checked(:always), otherwise, the .on_failure has no effect.") - end - decl.checked = default_checked_level - end - if decl.on_failure.equal?(ARG_NOT_PROVIDED) - decl.on_failure = nil - end - if decl.params.equal?(ARG_NOT_PROVIDED) - decl.params = {} - end - if decl.type_parameters.equal?(ARG_NOT_PROVIDED) - decl.type_parameters = {} - end - - decl.finalized = true - - self - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb deleted file mode 100644 index 53d9a93195..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Methods::Modes - def self.standard - 'standard' - end - def self.abstract - 'abstract' - end - def self.overridable - 'overridable' - end - def self.override - 'override' - end - def self.overridable_override - 'overridable_override' - end - def self.untyped - 'untyped' - end - MODES = [self.standard, self.abstract, self.overridable, self.override, self.overridable_override, self.untyped].freeze - - OVERRIDABLE_MODES = [self.override, self.overridable, self.overridable_override, self.untyped, self.abstract].freeze - OVERRIDE_MODES = [self.override, self.overridable_override].freeze - NON_OVERRIDE_MODES = MODES - OVERRIDE_MODES -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb deleted file mode 100644 index bd15977bd5..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb +++ /dev/null @@ -1,225 +0,0 @@ -# frozen_string_literal: true -# typed: true - -class T::Private::Methods::Signature - attr_reader :method, :method_name, :arg_types, :kwarg_types, :block_type, :block_name, - :rest_type, :rest_name, :keyrest_type, :keyrest_name, :bind, - :return_type, :mode, :req_arg_count, :req_kwarg_names, :has_rest, :has_keyrest, - :check_level, :parameters, :on_failure, :override_allow_incompatible, - :defined_raw - - def self.new_untyped(method:, mode: T::Private::Methods::Modes.untyped, parameters: method.parameters) - # Using `Untyped` ensures we'll get an error if we ever try validation on these. - not_typed = T::Private::Types::NotTyped.new - raw_return_type = not_typed - # Map missing parameter names to "argN" positionally - parameters = parameters.each_with_index.map do |(param_kind, param_name), index| - [param_kind, param_name || "arg#{index}"] - end - raw_arg_types = parameters.map do |_param_kind, param_name| - [param_name, not_typed] - end.to_h - - self.new( - method: method, - method_name: method.name, - raw_arg_types: raw_arg_types, - raw_return_type: raw_return_type, - bind: nil, - mode: mode, - check_level: :never, - parameters: parameters, - on_failure: nil, - ) - end - - def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false, defined_raw: false) - @method = method - @method_name = method_name - @arg_types = [] - @kwarg_types = {} - @block_type = nil - @block_name = nil - @rest_type = nil - @rest_name = nil - @keyrest_type = nil - @keyrest_name = nil - @return_type = T::Utils.coerce(raw_return_type) - @bind = bind ? T::Utils.coerce(bind) : bind - @mode = mode - @check_level = check_level - @req_arg_count = 0 - @req_kwarg_names = [] - @has_rest = false - @has_keyrest = false - @parameters = parameters - @on_failure = on_failure - @override_allow_incompatible = override_allow_incompatible - @defined_raw = defined_raw - - declared_param_names = raw_arg_types.keys - # If sig params are declared but there is a single parameter with a missing name - # **and** the method ends with a "=", assume it is a writer method generated - # by attr_writer or attr_accessor - writer_method = declared_param_names != [nil] && parameters == [[:req]] && 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 - param_names = parameters.map {|_, name| name} - missing_names = param_names - declared_param_names - extra_names = declared_param_names - param_names - if !missing_names.empty? - raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}" - end - if !extra_names.empty? - raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}" - end - - if parameters.size != raw_arg_types.size - raise "The declaration for `#{method.name}` has arguments with duplicate names" - end - - parameters.zip(raw_arg_types) do |(param_kind, param_name), (type_name, raw_type)| - if type_name != param_name - hint = "" - # Ruby reorders params so that required keyword arguments - # 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} - 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." - end - - raise "Parameter `#{type_name}` is declared out of order (declared as arg number " \ - "#{declared_param_names.index(type_name) + 1}, defined in the method as arg number " \ - "#{param_names.index(type_name) + 1}).#{hint}\nMethod: #{method_desc}" - end - - type = T::Utils.coerce(raw_type) - - case param_kind - when :req - if @arg_types.length > @req_arg_count - # Note that this is actually is supported by Ruby, but it would add complexity to - # support it here, and I'm happy to discourage its use anyway. - # - # If you are seeing this error and surprised by it, it's possible that you have - # overridden the method described in the error message. For example, Rails defines - # def self.update!(id = :all, attributes) - # on AR models. If you have also defined `self.update!` on an AR model you might - # see this error. The simplest resolution is to rename your method. - raise "Required params after optional params are not supported in method declarations. Method: #{method_desc}" - end - @arg_types << [param_name, type] - @req_arg_count += 1 - when :opt - @arg_types << [param_name, type] - when :key, :keyreq - @kwarg_types[param_name] = type - if param_kind == :keyreq - @req_kwarg_names << param_name - end - when :block - @block_name = param_name - @block_type = type - when :rest - @has_rest = true - @rest_name = param_name - @rest_type = type - when :keyrest - @has_keyrest = true - @keyrest_name = param_name - @keyrest_type = type - else - raise "Unexpected param_kind: `#{param_kind}`. Method: #{method_desc}" - end - end - end - - attr_writer :method_name - protected :method_name= - - def as_alias(alias_name) - new_sig = clone - new_sig.method_name = alias_name - new_sig - end - - def arg_count - @arg_types.length - end - - def kwarg_names - @kwarg_types.keys - end - - def owner - @method.owner - end - - def dsl_method - "#{@mode}_method" - end - - # @return [Hash] a mapping like `{arg_name: [val, type], ...}`, for only those args actually present. - def each_args_value_type(args) - # Manually split out args and kwargs based on ruby's behavior. Do not try to implement this by - # getting ruby to determine the kwargs for you (e.g., by defining this method to take *args and - # **kwargs). That won't work, because ruby's behavior for determining kwargs is dependent on the - # the other parameters in the method definition, and our method definition here doesn't (and - # can't) match the definition of the method we're validating. In addition, Ruby has a bug that - # causes forwarding **kwargs to do the wrong thing: see https://bugs.ruby-lang.org/issues/10708 - # and https://bugs.ruby-lang.org/issues/11860. - args_length = args.length - if (args_length > @req_arg_count) && (!@kwarg_types.empty? || @has_keyrest) && args[-1].is_a?(Hash) - kwargs = args[-1] - args_length -= 1 - else - kwargs = EMPTY_HASH - end - - arg_types = @arg_types - - if @has_rest - rest_count = args_length - @arg_types.length - rest_count = 0 if rest_count.negative? - - arg_types += [[@rest_name, @rest_type]] * rest_count - - elsif (args_length < @req_arg_count) || (args_length > @arg_types.length) - expected_str = @req_arg_count.to_s - if @arg_types.length != @req_arg_count - expected_str += "..#{@arg_types.length}" - end - raise ArgumentError.new("wrong number of arguments (given #{args_length}, expected #{expected_str})") - end - - begin - it = 0 - while it < args_length - yield arg_types[it][0], args[it], arg_types[it][1] - it += 1 - end - end - - kwargs.each do |name, val| - type = @kwarg_types[name] - if !type && @has_keyrest - type = @keyrest_type - end - yield name, val, type if type - end - end - - def method_desc - loc = if @method.source_location - @method.source_location.join(':') - else - "" - end - "#{@method} at #{loc}" - end - - EMPTY_HASH = {}.freeze -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb deleted file mode 100644 index 16188e0bf3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb +++ /dev/null @@ -1,225 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Methods::SignatureValidation - Methods = T::Private::Methods - Modes = Methods::Modes - - def self.validate(signature) - if signature.method_name == :initialize && signature.method.owner.is_a?(Class) - # Constructors are special. They look like overrides in terms of a super_method existing, - # but in practice, you never call them polymorphically. Conceptually, they're standard - # methods (this is consistent with how they're treated in other languages, e.g. Java) - if signature.mode != Modes.standard - raise "`initialize` should not use `.abstract` or `.implementation` or any other inheritance modifiers." - end - return - end - - super_method = signature.method.super_method - - if super_method && super_method.owner != signature.method.owner - Methods.maybe_run_sig_block_for_method(super_method) - super_signature = Methods.signature_for_method(super_method) - - # 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? - nil - else - # super_signature can be nil when we're overriding a method (perhaps a builtin) that didn't use - # one of the method signature helpers. Use an untyped signature so we can still validate - # everything but types. - # - # We treat these signatures as overridable, that way people can use `.override` with - # overrides of builtins. In the future we could try to distinguish when the method is a - # builtin and treat non-builtins as non-overridable (so you'd be forced to declare them with - # `.overridable`). - # - super_signature ||= Methods::Signature.new_untyped(method: super_method) - - validate_override_mode(signature, super_signature) - validate_override_shape(signature, super_signature) - validate_override_types(signature, super_signature) - end - else - validate_non_override_mode(signature) - end - end - - private_class_method def self.pretty_mode(signature) - if signature.mode == Modes.overridable_override - '.overridable.override' - else - ".#{signature.mode}" - end - end - - def self.validate_override_mode(signature, super_signature) - case signature.mode - when *Modes::OVERRIDE_MODES - # Peaceful - when *Modes::NON_OVERRIDE_MODES - if super_signature.mode == Modes.standard - # Peaceful - elsif super_signature.mode == Modes.abstract - raise "You must use `.override` when overriding the abstract method `#{signature.method_name}`.\n" \ - " Abstract definition: #{method_loc_str(super_signature.method)}\n" \ - " Implementation definition: #{method_loc_str(signature.method)}\n" - elsif super_signature.mode != Modes.untyped - raise "You must use `.override` when overriding the existing method `#{signature.method_name}`.\n" \ - " Parent definition: #{method_loc_str(super_signature.method)}\n" \ - " Child definition: #{method_loc_str(signature.method)}\n" - end - else - raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - end - - def self.validate_non_override_mode(signature) - case signature.mode - when Modes.override - if signature.method_name == :each && signature.method.owner < Enumerable - # Enumerable#each is the only method in Sorbet's RBI payload that defines an abstract method. - # Enumerable#each does not actually exist at runtime, but it is required to be implemented by - # any class which includes Enumerable. We want to declare Enumerable#each as abstract so that - # people can call it anything which implements the Enumerable interface, and so that it's a - # static error to forget to implement it. - # - # This is a one-off hack, and we should think carefully before adding more methods here. - nil - else - raise "You marked `#{signature.method_name}` as #{pretty_mode(signature)}, but that method doesn't already exist in this class/module to be overriden.\n" \ - " Either check for typos and for missing includes or super classes to make the parent method shows up\n" \ - " ... or remove #{pretty_mode(signature)} here: #{method_loc_str(signature.method)}\n" - end - when Modes.standard, *Modes::NON_OVERRIDE_MODES - # Peaceful - nil - else - raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - - # Given a singleton class, we can check if it belongs to a - # module by looking at its superclass; given `module M`, - # `M.singleton_class.superclass == Module`, which is not true - # for any class. - owner = signature.method.owner - if (signature.mode == Modes.abstract || Modes::OVERRIDABLE_MODES.include?(signature.mode)) && - owner.singleton_class? && owner.superclass == Module - raise "Defining an overridable class method (via #{pretty_mode(signature)}) " \ - "on a module is not allowed. Class methods on " \ - "modules do not get inherited and thus cannot be overridden." - end - end - - def self.validate_override_shape(signature, super_signature) - return if signature.override_allow_incompatible - return if super_signature.mode == Modes.untyped - - method_name = signature.method_name - mode_verb = super_signature.mode == Modes.abstract ? 'implements' : 'overrides' - - if !signature.has_rest && signature.arg_count < super_signature.arg_count - raise "Your definition of `#{method_name}` must accept at least #{super_signature.arg_count} " \ - "positional arguments to be compatible with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - if !signature.has_rest && super_signature.has_rest - raise "Your definition of `#{method_name}` must have `*#{super_signature.rest_name}` " \ - "to be compatible with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - if signature.req_arg_count > super_signature.req_arg_count - raise "Your definition of `#{method_name}` must have no more than #{super_signature.req_arg_count} " \ - "required argument(s) to be compatible with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - if !signature.has_keyrest - # O(nm), but n and m are tiny here - missing_kwargs = super_signature.kwarg_names - signature.kwarg_names - if !missing_kwargs.empty? - raise "Your definition of `#{method_name}` is missing these keyword arg(s): #{missing_kwargs} " \ - "which are defined in the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - end - - if !signature.has_keyrest && super_signature.has_keyrest - raise "Your definition of `#{method_name}` must have `**#{super_signature.keyrest_name}` " \ - "to be compatible with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - # O(nm), but n and m are tiny here - extra_req_kwargs = signature.req_kwarg_names - super_signature.req_kwarg_names - if !extra_req_kwargs.empty? - raise "Your definition of `#{method_name}` has extra required keyword arg(s) " \ - "#{extra_req_kwargs} relative to the method it #{mode_verb}, making it incompatible: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - if super_signature.block_name && !signature.block_name - raise "Your definition of `#{method_name}` must accept a block parameter to be compatible " \ - "with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - end - - def self.validate_override_types(signature, super_signature) - return if signature.override_allow_incompatible - return if super_signature.mode == Modes.untyped - return unless [signature, super_signature].all? do |sig| - sig.check_level == :always || sig.check_level == :compiled || (sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) - end - mode_noun = super_signature.mode == Modes.abstract ? 'implementation' : 'override' - - # arg types must be contravariant - super_signature.arg_types.zip(signature.arg_types).each_with_index do |((_super_name, super_type), (name, type)), index| - if !super_type.subtype_of?(type) - raise "Incompatible type for arg ##{index + 1} (`#{name}`) in signature for #{mode_noun} of method " \ - "`#{signature.method_name}`:\n" \ - "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \ - "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \ - "(The types must be contravariant.)" - end - end - - # kwarg types must be contravariant - super_signature.kwarg_types.each do |name, super_type| - type = signature.kwarg_types[name] - if !super_type.subtype_of?(type) - raise "Incompatible type for arg `#{name}` in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \ - "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \ - "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \ - "(The types must be contravariant.)" - end - end - - # return types must be covariant - if !signature.return_type.subtype_of?(super_signature.return_type) - raise "Incompatible return type in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \ - "* Base: `#{super_signature.return_type}` (in #{method_loc_str(super_signature.method)})\n" \ - "* #{mode_noun.capitalize}: `#{signature.return_type}` (in #{method_loc_str(signature.method)})\n" \ - "(The types must be covariant.)" - end - 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)}" \ - "\n * #{mode_noun}: in #{method_loc_str(signature.method)}" - end - - private_class_method def self.method_loc_str(method) - loc = if method.source_location - method.source_location.join(':') - else - "" - end - "#{method.owner} at #{loc}" - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb deleted file mode 100644 index 01eb42bd3a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private - module MixesInClassMethods - def included(other) - mods = Abstract::Data.get(self, :class_methods_mixins) - mods.each {|mod| other.extend(mod)} - super - end - end - - module Mixins - def self.declare_mixes_in_class_methods(mixin, class_methods) - if mixin.is_a?(Class) - raise "Classes cannot be used as mixins, and so mixes_in_class_methods cannot be used on a Class." - end - - if Abstract::Data.key?(mixin, :class_methods_mixins) - class_methods = Abstract::Data.get(mixin, :class_methods_mixins) + class_methods - end - - mixin.singleton_class.include(MixesInClassMethods) - Abstract::Data.set(mixin, :class_methods_mixins, class_methods) - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb deleted file mode 100644 index 7b2822d394..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Retry - - # A special singleton used for static analysis of exceptions. - module RETRY - freeze - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb deleted file mode 100644 index 2454b21988..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# Used in `sig.checked(level)` to determine when runtime type checking -# is enabled on a method. -module T::Private::RuntimeLevels - LEVELS = [ - # Validate every call in every environment - :always, - # Validate in tests, but not in production - :tests, - # Don't even validate in tests, b/c too expensive, - # or b/c we fully trust the static typing - :never, - # Validate the sig when the file is using the Sorbet Compiler. - # Behaves like :never when interpreted. - :compiled, - ].freeze - - @check_tests = false - @wrapped_tests_with_validation = false - - @has_read_default_checked_level = false - @default_checked_level = :always - - def self.check_tests? - # Assume that this code path means that some `sig.checked(:tests)` - # has been wrapped (or not wrapped) already, which is a trapdoor - # for toggling `@check_tests`. - @wrapped_tests_with_validation = true - - @check_tests - end - - 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- ") - raise "Toggle `:tests`-level runtime type checking earlier. " \ - "There are already some methods wrapped with `sig.checked(:tests)`:\n" \ - "- #{locations}" - end - - _toggle_checking_tests(true) - end - - def self.default_checked_level - @has_read_default_checked_level = true - @default_checked_level - end - - def self.default_checked_level=(default_checked_level) - if @has_read_default_checked_level - raise "Set the default checked level earlier. There are already some methods whose sig blocks have evaluated which would not be affected by the new default." - end - @default_checked_level = default_checked_level - end - - def self._toggle_checking_tests(checked) - @check_tests = checked - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb deleted file mode 100644 index 62e19fb088..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private::Sealed - module NoInherit - def inherited(child) - super - this_line = Kernel.caller.find {|line| !line.match(/in `inherited'$/)} - T::Private::Sealed.validate_inheritance(this_line, self, child, 'inherited') - @sorbet_sealed_module_all_subclasses << child - end - - def sealed_subclasses - @sorbet_sealed_module_all_subclasses_set ||= # rubocop:disable Naming/MemoizedInstanceVariableName - begin - require 'set' - Set.new(@sorbet_sealed_module_all_subclasses).freeze - end - end - end - - module NoIncludeExtend - def included(child) - super - this_line = Kernel.caller.find {|line| !line.match(/in `included'$/)} - T::Private::Sealed.validate_inheritance(this_line, self, child, 'included') - @sorbet_sealed_module_all_subclasses << child - end - - def extended(child) - super - this_line = Kernel.caller.find {|line| !line.match(/in `extended'$/)} - T::Private::Sealed.validate_inheritance(this_line, self, child, 'extended') - @sorbet_sealed_module_all_subclasses << child - end - - def sealed_subclasses - # this will freeze the set so that you can never get into a - # state where you use the subclasses list and then something - # else will add to it - @sorbet_sealed_module_all_subclasses_set ||= # rubocop:disable Naming/MemoizedInstanceVariableName - begin - require 'set' - Set.new(@sorbet_sealed_module_all_subclasses).freeze - end - end - end - - def self.declare(mod, decl_file) - if !mod.is_a?(Module) - raise "#{mod} is not a class or module and cannot be declared `sealed!`" - end - if sealed_module?(mod) - raise "#{mod} was already declared `sealed!` and cannot be re-declared `sealed!`" - end - if T::Private::Final.final_module?(mod) - raise "#{mod} was already declared `final!` and cannot be declared `sealed!`" - end - mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend) - if !decl_file - raise "Couldn't determine declaration file for sealed class." - end - mod.instance_variable_set(:@sorbet_sealed_module_decl_file, decl_file) - mod.instance_variable_set(:@sorbet_sealed_module_all_subclasses, []) - end - - def self.sealed_module?(mod) - mod.instance_variable_defined?(:@sorbet_sealed_module_decl_file) - end - - def self.validate_inheritance(this_line, parent, child, verb) - this_file = this_line&.split(':')&.first - decl_file = parent.instance_variable_get(:@sorbet_sealed_module_decl_file) if sealed_module?(parent) - - if !this_file - raise "Could not use backtrace to determine file for #{verb} child #{child}" - end - if !decl_file - raise "#{parent} does not seem to be a sealed module (#{verb} by #{child})" - end - - if !this_file.start_with?(decl_file) - whitelist = T::Configuration.sealed_violation_whitelist - if !whitelist.nil? && whitelist.any? {|pattern| this_file =~ pattern} - return - end - - raise "#{parent} was declared sealed and can only be #{verb} in #{decl_file}, not #{this_file}" - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb deleted file mode 100644 index 57196553b6..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# A placeholder for when an untyped thing must provide a type. -# Raises an exception if it is ever used for validation. -class T::Private::Types::NotTyped < T::Types::Base - ERROR_MESSAGE = "Validation is being done on a `NotTyped`. Please report this bug at https://github.com/sorbet/sorbet/issues" - - # overrides Base - def name - "" - end - - # overrides Base - def valid?(obj) - raise ERROR_MESSAGE - end - - # overrides Base - private def subtype_of_single?(other) - raise ERROR_MESSAGE - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb deleted file mode 100644 index b2295f7730..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# Holds a string. Useful for showing type aliases in error messages -class T::Private::Types::StringHolder < T::Types::Base - attr_reader :string - - def initialize(string) - @string = string - end - - # overrides Base - def name - string - end - - # overrides Base - def valid?(obj) - false - end - - # overrides Base - private def subtype_of_single?(other) - false - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb deleted file mode 100644 index de805c9659..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Types - # Wraps a proc for a type alias to defer its evaluation. - class TypeAlias < T::Types::Base - - def initialize(callable) - @callable = callable - end - - def aliased_type - @aliased_type ||= T::Utils.coerce(@callable.call) - end - - # overrides Base - def name - aliased_type.name - end - - # overrides Base - def recursively_valid?(obj) - aliased_type.recursively_valid?(obj) - end - - # overrides Base - def valid?(obj) - aliased_type.valid?(obj) - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb deleted file mode 100644 index 310fc56abc..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# A marking class for when methods return void. -# Should never appear in types directly. -class T::Private::Types::Void < T::Types::Base - ERROR_MESSAGE = "Validation is being done on an `Void`. Please report this bug at https://github.com/sorbet/sorbet/issues" - - # The actual return value of `.void` methods. - # - # Uses `module VOID` because this gives it a readable name when someone - # examines it in Pry or with `#inspect` like: - # - # T::Private::Types::Void::VOID - # - module VOID - freeze - end - - # overrides Base - def name - "" - end - - # overrides Base - def valid?(obj) - raise ERROR_MESSAGE - end - - # overrides Base - private def subtype_of_single?(other) - raise ERROR_MESSAGE - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb deleted file mode 100644 index fae252aa04..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb +++ /dev/null @@ -1,169 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# A mixin for defining typed properties (attributes). -# To get serialization methods (to/from JSON-style hashes), add T::Props::Serializable. -# To get a constructor based on these properties, inherit from T::Struct. -module T::Props - extend T::Helpers - - ##### - # CAUTION: This mixin is used in hundreds of classes; we want to keep its surface area as narrow - # as possible and avoid polluting (and possibly conflicting with) the classes that use it. - # - # It currently has *zero* instance methods; let's try to keep it that way. - # For ClassMethods (below), try to add things to T::Props::Decorator instead unless you are sure - # it needs to be exposed here. - ##### - - module ClassMethods - extend T::Sig - extend T::Helpers - - def props - decorator.props - end - def plugins - @plugins ||= [] - end - - def decorator_class - Decorator - end - - def decorator - @decorator ||= decorator_class.new(self) - end - def reload_decorator! - @decorator = decorator_class.new(self) - end - - # Define a new property. See {file:README.md} for some concrete - # examples. - # - # Defining a property defines a method with the same name as the - # property, that returns the current value, and a `prop=` method - # to set its value. Properties will be inherited by subclasses of - # a document class. - # - # @param name [Symbol] The name of this property - # @param cls [Class,T::Types::Base] The type of this - # property. If the type is itself a `Document` subclass, this - # property will be recursively serialized/deserialized. - # @param rules [Hash] Options to control this property's behavior. - # @option rules [T::Boolean,Symbol] :optional If `true`, this property - # is never required to be set before an instance is serialized. - # If `:on_load` (default), when this property is missing or nil, a - # new model cannot be saved, and an existing model can only be - # saved if the property was already missing when it was loaded. - # If `false`, when the property is missing/nil after deserialization, it - # will be set to the default value (as defined by the `default` or - # `factory` option) or will raise if they are not present. - # Deprecated: For `Model`s, if `:optional` is set to the special value - # `:existing`, the property can be saved as nil even if it was - # deserialized with a non-nil value. (Deprecated because there should - # never be a need for this behavior; the new behavior of non-optional - # properties should be sufficient.) - # @option rules [Array] :enum An array of legal values; The - # property is required to take on one of those values. - # @option rules [T::Boolean] :dont_store If true, this property will - # not be saved on the hash resulting from - # {T::Props::Serializable#serialize} - # @option rules [Object] :ifunset A value to be returned if this - # property is requested but has never been set (is set to - # `nil`). It is applied at property-access time, and never saved - # back onto the object or into the database. - # - # ``:ifunset`` is considered **DEPRECATED** and should not be used - # in new code, in favor of just setting a default value. - # @option rules [Model, Symbol, Proc] :foreign A model class that this - # property is a reference to. Passing `:foreign` will define a - # `:"#{name}_"` method, that will load and return the - # corresponding foreign model. - # - # A symbol can be passed to avoid load-order dependencies; It - # will be lazily resolved relative to the enclosing module of the - # defining class. - # - # A callable (proc or method) can be passed to dynamically specify the - # foreign model. This will be passed the object instance so that other - # properties of the object can be used to determine the relevant model - # class. It should return a string/symbol class name or the foreign model - # class directly. - # - # @option rules [Object] :default A default value that will be set - # by `#initialize` if none is provided in the initialization - # hash. This will not affect objects loaded by {.from_hash}. - # @option rules [Proc] :factory A `Proc` that will be called to - # generate an initial value for this prop on `#initialize`, if - # none is provided. - # @option rules [T::Boolean] :immutable If true, this prop cannot be - # modified after an instance is created or loaded from a hash. - # @option rules [T::Boolean] :override It is an error to redeclare a - # `prop` that has already been declared (including on a - # superclass), unless `:override` is set to `true`. - # @option rules [Symbol, Array] :redaction A redaction directive that may - # be passed to Chalk::Tools::RedactionUtils.redact_with_directive to - # sanitize this parameter for display. Will define a - # `:"#{name}_redacted"` method, which will return the value in sanitized - # form. - # - # @return [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) - end - - # Validates the value of the specified prop. This method allows the caller to - # validate a value for a prop without having to set the data on the instance. - # Throws if invalid. - # - # @param prop [Symbol] - # @param val [Object] - # @return [void] - def validate_prop_value(prop, val) - decorator.validate_prop_value(prop, val) - end - - # Needs to be documented - def plugin(mod) - decorator.plugin(mod) - end - - # Shorthand helper to define a `prop` with `immutable => true` - sig {params(name: Symbol, cls_or_args: T.untyped, args: T::Hash[Symbol, 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") - end - - if cls_or_args.is_a?(Hash) - self.prop(name, cls_or_args.merge(immutable: true)) - else - self.prop(name, cls_or_args, args.merge(immutable: true)) - end - end - - def included(child) - decorator.model_inherited(child) - super - end - - def prepended(child) - decorator.model_inherited(child) - super - end - - def extended(child) - decorator.model_inherited(child.singleton_class) - super - end - - def inherited(child) - decorator.model_inherited(child) - super - end - end - mixes_in_class_methods(ClassMethods) -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb deleted file mode 100644 index 570c068ac4..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::Constructor - include T::Props::WeakConstructor -end - -module T::Props::Constructor::DecoratorMethods - extend T::Sig - - # Set values for all props that have no defaults. Override what `WeakConstructor` - # does in order to raise errors on nils instead of ignoring them. - # - # @return [Integer] A count of props that we successfully initialized (which - # 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)} - 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. - result = 0 - props_without_defaults&.each_pair do |p, setter_proc| - begin - val = hash[p] - instance.instance_exec(val, &setter_proc) - if val || hash.key?(p) - result += 1 - end - rescue TypeError, T::Props::InvalidValueError - if !hash.key?(p) - raise ArgumentError.new("Missing required prop `#{p}` for class `#{instance.class.name}`") - else - raise - end - end - end - result - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb deleted file mode 100644 index 0df6a0d863..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb +++ /dev/null @@ -1,108 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module CustomType - extend T::Sig - extend T::Helpers - - abstract! - - include Kernel # for `is_a?` - - # Alias for backwards compatibility - sig(:final) do - params( - value: BasicObject, - ) - .returns(T::Boolean) - .checked(:never) - end - def instance?(value) - self.===(value) - end - - # Alias for backwards compatibility - sig(:final) do - params( - value: BasicObject, - ) - .returns(T::Boolean) - .checked(:never) - end - def valid?(value) - instance?(value) - end - - # Given an instance of this type, serialize that into a scalar type - # supported by 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)} - def serialize(instance); end - - # Given the serialized form of your type, this returns an instance - # of that custom type representing that value. - # - # @param scalar One of T::Configuration.scalar_types - # @return Object - sig {abstract.params(scalar: T.untyped).returns(T.untyped).checked(:never)} - def deserialize(scalar); end - - 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: Object).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 - # are all classes. - klass = T.let(val.class, T.nilable(Class)) - until klass.nil? - return true if T::Configuration.scalar_types.include?(klass.to_s) - klass = klass.superclass - end - false - end - - # We allow custom types to serialize to Arrays, so that we can - # 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)} - def self.valid_serialization?(val) - case val - when Array - val.each do |v| - return false unless scalar_type?(v) - end - - true - else - scalar_type?(val) - end - end - - sig(:final) do - params(instance: Object) - .returns(T.untyped) - .checked(:never) - end - def self.checked_serialize(instance) - val = T.cast(instance.class, T::Props::CustomType).serialize(instance) - unless valid_serialization?(val) - msg = "#{instance.class} did not serialize to a valid scalar type. It became a: #{val.class}" - if val.is_a?(Hash) - msg += "\nIf you want to store a structured Hash, consider using a T::Struct as your type." - end - raise TypeError.new(msg) - end - val - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb deleted file mode 100644 index 679a32584b..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb +++ /dev/null @@ -1,669 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -# NB: This is not actually a decorator. It's just named that way for consistency -# with DocumentDecorator and ModelDecorator (which both seem to have been written -# with an incorrect understanding of the decorator pattern). These "decorators" -# should really just be static methods on private modules (we'd also want/need to -# replace decorator overrides in plugins with class methods that expose the necessary -# functionality). -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)} - - class NoRulesError < StandardError; end - - EMPTY_PROPS = T.let({}.freeze, T::Hash[Symbol, Rules]) - private_constant :EMPTY_PROPS - - 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| - T::Props::Plugin::Private.apply_decorator_methods(mod, self) - end - @props = T.let(EMPTY_PROPS, T::Hash[Symbol, Rules]) - end - - # checked(:never) - O(prop accesses) - sig {returns(T::Hash[Symbol, Rules]).checked(:never)} - attr_reader :props - - 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)} - 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)} - def add_prop_definition(prop, rules) - override = rules.delete(:override) - - if props.include?(prop) && !override - raise ArgumentError.new("Attempted to redefine prop #{prop.inspect} that's already defined without specifying :override => true: #{prop_rules(prop)}") - elsif !props.include?(prop) && override - raise ArgumentError.new("Attempted to override a prop #{prop.inspect} that doesn't already exist") - end - - @props = @props.merge(prop => rules.freeze).freeze - end - - # Heads up! - # - # There are already too many ad-hoc options on the prop DSL. - # - # We have already done a lot of work to remove unnecessary and confusing - # options. If you're considering adding a new rule key, please come chat with - # the Sorbet team first, as we'd really like to learn more about how to best - # solve the problem you're encountering. - VALID_RULE_KEYS = T.let(%i[ - enum - foreign - ifunset - immutable - override - redaction - sensitivity - without_accessors - clobber_existing_method! - extra - setter_validate - _tnilable - ].map {|k| [k, true]}.to_h.freeze, T::Hash[Symbol, T::Boolean]) - private_constant :VALID_RULE_KEYS - - 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)} - def decorated_class - @class - end - - # Accessors - - # 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)} - def validate_prop_value(prop, val) - # We call `setter_proc` here without binding to an instance, so it'll run - # `instance_variable_set` if validation passes, but nothing will care. - # We only care about the validation. - prop_rules(prop).fetch(:setter_proc).call(val) - end - - # For performance, don't use named params here. - # Passing in rules here is purely a performance optimization. - # Unlike the other methods that take rules, this one calls prop_rules for - # the default, which raises if the prop doesn't exist (this maintains - # preexisting behavior). - # - # Note this path is NOT used by generated setters on instances, - # which are defined using `setter_proc` directly. - # - # checked(:never) - O(prop accesses) - sig do - params( - instance: DecoratedInstance, - prop: Symbol, - val: T.untyped, - rules: Rules - ) - .void - .checked(:never) - end - def prop_set(instance, prop, val, rules=prop_rules(prop)) - instance.instance_exec(val, &rules.fetch(:setter_proc)) - end - alias_method :set, :prop_set - - # Only Models have any custom get logic but we need to call this on - # non-Models since we don't know at code gen time what we have. - sig do - params( - instance: DecoratedInstance, - prop: Symbol, - value: T.untyped - ) - .returns(T.untyped) - .checked(:never) - end - def prop_get_logic(instance, prop, value) - value - end - - # For performance, don't use named params here. - # Passing in rules here is purely a performance optimization. - # - # Note this path is NOT used by generated getters on instances, - # unless `ifunset` is used on the prop, or `prop_get` is overridden. - # - # checked(:never) - O(prop accesses) - sig do - params( - instance: DecoratedInstance, - prop: T.any(String, Symbol), - rules: Rules - ) - .returns(T.untyped) - .checked(:never) - end - def prop_get(instance, prop, rules=prop_rules(prop)) - val = instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key]) - if !val.nil? - val - elsif (d = rules[:ifunset]) - T::Props::Utils.deep_clone_object(d) - else - nil - end - end - - sig do - params( - instance: DecoratedInstance, - prop: T.any(String, Symbol), - rules: Rules - ) - .returns(T.untyped) - .checked(:never) - end - def prop_get_if_set(instance, prop, rules=prop_rules(prop)) - instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key]) - end - alias_method :get, :prop_get_if_set # Alias for backwards compatibility - - # checked(:never) - O(prop accesses) - sig do - params( - instance: DecoratedInstance, - prop: Symbol, - foreign_class: Module, - rules: Rules, - opts: T::Hash[Symbol, T.untyped], - ) - .returns(T.untyped) - .checked(:never) - end - def foreign_prop_get(instance, prop, foreign_class, rules=prop_rules(prop), opts={}) - return if !(value = prop_get(instance, prop, rules)) - T.unsafe(foreign_class).load(value, {}, opts) - 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(:never) - Rules hash is expensive to check - sig do - params( - name: Symbol, - cls: Module, - rules: Rules, - type: PropTypeOrClass - ) - .void - .checked(:never) - end - def prop_validate_definition!(name, cls, rules, type) - validate_prop_name(name) - - if rules.key?(:pii) - raise ArgumentError.new("The 'pii:' option for props has been renamed " \ - "to 'sensitivity:' (in prop #{@class.name}.#{name})") - end - - 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 - - if !rules[:clobber_existing_method!] && !rules[:without_accessors] && BANNED_METHOD_NAMES.include?(name.to_sym) - raise ArgumentError.new( - "#{name} can't be used as a prop in #{@class} because a method with " \ - "that name already exists (defined by #{@class.instance_method(name).owner} " \ - "at #{@class.instance_method(name).source_location || ''}). " \ - "(If using this name is unavoidable, try `without_accessors: true`.)" - ) - end - - extra = rules[:extra] - if !extra.nil? && !extra.is_a?(Hash) - raise ArgumentError.new("Extra metadata must be a Hash in prop #{@class.name}.#{name}") - end - - nil - end - - SAFE_NAME = T.let(/\A[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp) - - # Used to validate both prop names and serialized forms - sig {params(name: T.any(Symbol, String)).void} - private def validate_prop_name(name) - if !name.match?(SAFE_NAME) - raise ArgumentError.new("Invalid prop name in #{@class.name}: #{name}") - end - end - - # This converts the type from a T::Type to a regular old ruby class. - sig {params(type: T::Types::Base).returns(Module)} - private def convert_type_to_class(type) - case type - when T::Types::TypedArray, T::Types::FixedArray - Array - when T::Types::TypedHash, T::Types::FixedHash - Hash - when T::Types::TypedSet - Set - when T::Types::Union - # The below unwraps our T.nilable types for T::Props if we can. - # This lets us do things like specify: const T.nilable(String), foreign: Opus::DB::Model::Merchant - non_nil_type = T::Utils.unwrap_nilable(type) - if non_nil_type - convert_type_to_class(non_nil_type) - else - Object - end - when T::Types::Simple - type.raw_type - else - # This isn't allowed unless whitelisted_for_underspecification is - # true, due to the check in prop_validate_definition - Object - end - end - - # Returns `true` when the type of the prop is nilable, or the field is typed - # as `T.untyped`, a `:default` is present in the rules hash, and its value is - # `nil`. The latter case is a workaround for explicitly not supporting the use - # of `T.nilable(T.untyped)`. - # - # checked(:never) - Rules hash is expensive to check - sig do - params( - cls: PropTypeOrClass, - rules: Rules, - ) - .void - .checked(:never) - end - private def prop_nilable?(cls, rules) - T::Utils::Nilable.is_union_with_nilclass(cls) || (cls == T.untyped && rules.key?(:default) && rules[:default].nil?) - end - - # checked(:never) - Rules hash is expensive to check - sig do - params( - name: T.any(Symbol, String), - cls: PropTypeOrClass, - rules: Rules, - ) - .void - .checked(:never) - end - def prop_defined(name, cls, rules={}) - cls = T::Utils.resolve_alias(cls) - - if prop_nilable?(cls, rules) - # :_tnilable is introduced internally for performance purpose so that clients do not need to call - # T::Utils::Nilable.is_tnilable(cls) again. - # It is strictly internal: clients should always use T::Props::Utils.required_prop?() or - # T::Props::Utils.optional_prop?() for checking whether a field is required or optional. - rules[:_tnilable] = true - end - - name = name.to_sym - type = cls - if !cls.is_a?(Module) - cls = convert_type_to_class(cls) - end - type_object = smart_coerce(type, enum: rules[:enum]) - - prop_validate_definition!(name, cls, rules, type_object) - - # Retrive the possible underlying object with T.nilable. - type = T::Utils::Nilable.get_underlying_type(type) - - sensitivity_and_pii = {sensitivity: rules[:sensitivity]} - normalize = T::Configuration.normalize_sensitivity_and_pii_handler - if normalize - sensitivity_and_pii = normalize.call(sensitivity_and_pii) - - # We check for Class so this is only applied on concrete - # documents/models; We allow mixins containing props to not - # specify their PII nature, as long as every class into which they - # are ultimately included does. - # - if sensitivity_and_pii[:pii] && @class.is_a?(Class) && !T.unsafe(@class).contains_pii? - raise ArgumentError.new( - 'Cannot include a pii prop in a class that declares `contains_no_pii`' - ) - end - end - - rules = rules.merge( - # TODO: The type of this element is confusing. We should refactor so that - # it can be always `type_object` (a PropType) or always `cls` (a Module) - type: type, - type_object: type_object, - accessor_key: "@#{name}".to_sym, - sensitivity: sensitivity_and_pii[:sensitivity], - pii: sensitivity_and_pii[:pii], - # extra arbitrary metadata attached by the code defining this property - extra: rules[:extra]&.freeze, - ) - - validate_not_missing_sensitivity(name, rules) - - # for backcompat (the `:array` key is deprecated but because the name is - # so generic it's really hard to be sure it's not being relied on anymore) - if type.is_a?(T::Types::TypedArray) - inner = T::Utils::Nilable.get_underlying_type(type.type) - if inner.is_a?(Module) - rules[:array] = inner - end - end - - rules[:setter_proc] = T::Props::Private::SetterFactory.build_setter_proc(@class, name, rules).freeze - - add_prop_definition(name, rules) - - # NB: using `without_accessors` doesn't make much sense unless you also define some other way to - # get at the property (e.g., Chalk::ODM::Document exposes `get` and `set`). - define_getter_and_setter(name, rules) unless rules[:without_accessors] - - handle_foreign_option(name, cls, rules, rules[:foreign]) if rules[:foreign] - handle_redaction_option(name, rules[:redaction]) if rules[:redaction] - end - - # checked(:never) - Rules hash is expensive to check - 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] - if method(:prop_set).owner != T::Props::Decorator - @class.send(:define_method, "#{name}=") do |val| - T.unsafe(self.class).decorator.prop_set(self, name, val, rules) - end - else - # Fast path (~4x faster as of Ruby 2.6) - @class.send(:define_method, "#{name}=", &rules.fetch(:setter_proc)) - end - end - - if method(:prop_get).owner != T::Props::Decorator || rules.key?(:ifunset) - @class.send(:define_method, name) do - T.unsafe(self.class).decorator.prop_get(self, name, rules) - end - else - # Fast path (~30x faster as of Ruby 2.6) - @class.send(:attr_reader, name) # send is used because `attr_reader` is private in 2.4 - end - end - end - - sig do - params(type: PropTypeOrClass, enum: T.untyped) - .returns(T::Types::Base) - end - private def smart_coerce(type, enum:) - # Backwards compatibility for pre-T::Types style - type = T::Utils.coerce(type) - if enum.nil? - type - else - nonnil_type = T::Utils.unwrap_nilable(type) - if nonnil_type - T.unsafe(T.nilable(T.all(nonnil_type, T.deprecated_enum(enum)))) - else - T.unsafe(T.all(T.unsafe(type), T.deprecated_enum(enum))) - end - end - end - - # checked(:never) - Rules hash is expensive to check - 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] - T::Configuration.hard_assert_handler( - "#{@class}##{prop_name} has a 'redaction:' annotation but no " \ - "'sensitivity:' annotation. This is probably wrong, because if a " \ - "prop needs redaction then it is probably sensitive. Add a " \ - "sensitivity annotation like 'sensitivity: Opus::Sensitivity::PII." \ - "whatever', or explicitly override this check with 'sensitivity: []'." - ) - end - # TODO(PRIVACYENG-982) Ideally we'd also check for 'password' and possibly - # other terms, but this interacts badly with ProtoDefinedDocument because - # the proto syntax currently can't declare "sensitivity: []" - if /\bsecret\b/.match?(prop_name) - T::Configuration.hard_assert_handler( - "#{@class}##{prop_name} has the word 'secret' in its name, but no " \ - "'sensitivity:' annotation. This is probably wrong, because if a " \ - "prop is named 'secret' then it is probably sensitive. Add a " \ - "sensitivity annotation like 'sensitivity: Opus::Sensitivity::NonPII." \ - "security_token', or explicitly override this check with " \ - "'sensitivity: []'." - ) - end - end - end - - # Create `#{prop_name}_redacted` method - sig do - params( - prop_name: Symbol, - redaction: T.untyped, - ) - .void - end - private def handle_redaction_option(prop_name, redaction) - redacted_method = "#{prop_name}_redacted" - - @class.send(:define_method, redacted_method) do - value = self.public_send(prop_name) - handler = T::Configuration.redaction_handler - if !handler - raise "Using `redaction:` on a prop requires specifying `T::Configuration.redaction_handler`" - end - handler.call(value, redaction) - end - end - - sig do - params( - option_sym: Symbol, - foreign: T.untyped, - valid_type_msg: String, - ) - .void - end - private def validate_foreign_option(option_sym, foreign, valid_type_msg:) - if foreign.is_a?(Symbol) || foreign.is_a?(String) - raise ArgumentError.new( - "Using a symbol/string for `#{option_sym}` is no longer supported. Instead, use a Proc " \ - "that returns the class, e.g., foreign: -> {Foo}" - ) - end - - if !foreign.is_a?(Proc) && !foreign.is_a?(Array) && !foreign.respond_to?(:load) - raise ArgumentError.new("The `#{option_sym}` option must be #{valid_type_msg}") - end - end - - # checked(:never) - Rules hash is expensive to check - sig do - params( - prop_name: T.any(String, Symbol), - rules: Rules, - foreign: T.untyped, - ) - .void - .checked(:never) - end - private def define_foreign_method(prop_name, rules, foreign) - fk_method = "#{prop_name}_" - - # n.b. there's no clear reason *not* to allow additional options - # here, but we're baking in `allow_direct_mutation` since we - # *haven't* allowed additional options in the past and want to - # default to keeping this interface narrow. - @class.send(:define_method, fk_method) do |allow_direct_mutation: nil| - foreign = T.let(foreign, T.untyped) - if foreign.is_a?(Proc) - resolved_foreign = foreign.call - if !resolved_foreign.respond_to?(:load) - raise ArgumentError.new( - "The `foreign` proc for `#{prop_name}` must return a model class. " \ - "Got `#{resolved_foreign.inspect}` instead." - ) - end - # `foreign` is part of the closure state, so this will persist to future invocations - # of the method, optimizing it so this only runs on the first invocation. - foreign = resolved_foreign - end - opts = if allow_direct_mutation.nil? - {} - else - {allow_direct_mutation: allow_direct_mutation} - end - - T.unsafe(self.class).decorator.foreign_prop_get(self, prop_name, foreign, rules, opts) - end - - force_fk_method = "#{fk_method}!" - @class.send(:define_method, force_fk_method) do |allow_direct_mutation: nil| - loaded_foreign = send(fk_method, allow_direct_mutation: allow_direct_mutation) - if !loaded_foreign - T::Configuration.hard_assert_handler( - 'Failed to load foreign model', - storytime: {method: force_fk_method, class: self.class} - ) - end - loaded_foreign - end - end - - # checked(:never) - Rules hash is expensive to check - sig do - params( - prop_name: Symbol, - prop_cls: Module, - rules: Rules, - foreign: T.untyped, - ) - .void - .checked(:never) - end - private def handle_foreign_option(prop_name, prop_cls, rules, foreign) - validate_foreign_option( - :foreign, foreign, valid_type_msg: "a model class or a Proc that returns one" - ) - - if prop_cls != String - raise ArgumentError.new("`foreign` can only be used with a prop type of String") - end - - if foreign.is_a?(Array) - # We don't support arrays with `foreign` because it's hard to both preserve ordering and - # keep them from being lurky performance hits by issuing a bunch of un-batched DB queries. - # We could potentially address that by porting over something like AmbiguousIDLoader. - raise ArgumentError.new( - "Using an array for `foreign` is no longer supported. Instead, please use a union type of " \ - "token types for the prop type, e.g., T.any(Opus::Autogen::Tokens::FooModelToken, Opus::Autogen::Tokens::BarModelToken)" - ) - end - - unless foreign.is_a?(Proc) - T::Configuration.soft_assert_handler(<<~MESSAGE, storytime: {prop: prop_name, value: foreign}, notify: 'jerry') - Please use a Proc that returns a model class instead of the model class itself as the argument to `foreign`. In other words: - - instead of `prop :foo, String, foreign: FooModel` - use `prop :foo, String, foreign: -> {FooModel}` - - MESSAGE - end - - define_foreign_method(prop_name, rules, foreign) - end - - # TODO: rename this to props_inherited - # - # 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)} - def model_inherited(child) - child.extend(T::Props::ClassMethods) - child = T.cast(child, T.all(Module, T::Props::ClassMethods)) - - child.plugins.concat(decorated_class.plugins) - decorated_class.plugins.each do |mod| - # NB: apply_class_methods must not be an instance method on the decorator itself, - # otherwise we'd have to call child.decorator here, which would create the decorator - # before any `decorator_class` override has a chance to take effect (see the comment below). - T::Props::Plugin::Private.apply_class_methods(mod, child) - end - - props.each do |name, rules| - copied_rules = rules.dup - # NB: Calling `child.decorator` here is a timb bomb that's going to give someone a really bad - # time. Any class that defines props and also overrides the `decorator_class` method is going - # to reach this line before its override take effect, turning it into a no-op. - child.decorator.add_prop_definition(name, copied_rules) - - # It's a bit tricky to support `prop_get` hooks added by plugins without - # sacrificing the `attr_reader` fast path or clobbering customized getters - # defined manually on a child. - # - # To make this work, we _do_ clobber getters defined on the child, but only if: - # (a) it's needed in order to support a `prop_get` hook, and - # (b) it's safe because the getter was defined by this file. - # - unless rules[:without_accessors] - if clobber_getter?(child, name) - child.send(:define_method, name) do - T.unsafe(self.class).decorator.prop_get(self, name, rules) - end - end - - if !rules[:immutable] && clobber_setter?(child, name) - child.send(:define_method, "#{name}=") do |val| - T.unsafe(self.class).decorator.prop_set(self, name, val, rules) - end - end - end - end - end - - 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)} - 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)} - def plugin(mod) - decorated_class.plugins << mod - T::Props::Plugin::Private.apply_class_methods(mod, decorated_class) - T::Props::Plugin::Private.apply_decorator_methods(mod, self) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb deleted file mode 100644 index 6977f20471..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - class Error < StandardError; end - class InvalidValueError < Error; end - class ImmutableProp < Error; end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb deleted file mode 100644 index 91f256799d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb +++ /dev/null @@ -1,277 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Props - # Helper to validate generated code, to mitigate security concerns around - # `class_eval`. Not called by default; the expectation is this will be used - # in a test iterating over all T::Props::Serializable subclasses. - # - # We validate the exact expected structure of the generated methods as far - # as we can, and then where cloning produces an arbitrarily nested structure, - # we just validate a lack of side effects. - module GeneratedCodeValidation - extend Private::Parse - - class ValidationError < RuntimeError; end - - def self.validate_deserialize(source) - parsed = parse(source) - - # def %(hash) - # ... - # end - assert_equal(:def, parsed.type) - name, args, body = parsed.children - assert_equal(:__t_props_generated_deserialize, name) - assert_equal(s(:args, s(:arg, :hash)), args) - - assert_equal(:begin, body.type) - init, *prop_clauses, ret = body.children - - # found = % - # ... - # found - assert_equal(:lvasgn, init.type) - init_name, init_val = init.children - assert_equal(:found, init_name) - assert_equal(:int, init_val.type) - assert_equal(s(:lvar, :found), ret) - - prop_clauses.each_with_index do |clause, i| - if i.even? - validate_deserialize_hash_read(clause) - else - validate_deserialize_ivar_set(clause) - end - end - end - - def self.validate_serialize(source) - parsed = parse(source) - - # def %(strict) - # ... - # end - assert_equal(:def, parsed.type) - name, args, body = parsed.children - assert_equal(:__t_props_generated_serialize, name) - assert_equal(s(:args, s(:arg, :strict)), args) - - assert_equal(:begin, body.type) - init, *prop_clauses, ret = body.children - - # h = {} - # ... - # h - assert_equal(s(:lvasgn, :h, s(:hash)), init) - assert_equal(s(:lvar, :h), ret) - - prop_clauses.each do |clause| - validate_serialize_clause(clause) - end - end - - private_class_method def self.validate_serialize_clause(clause) - assert_equal(:if, clause.type) - condition, if_body, else_body = clause.children - - # if @%.nil? - assert_equal(:send, condition.type) - receiver, method = condition.children - assert_equal(:ivar, receiver.type) - assert_equal(:nil?, method) - - unless if_body.nil? - # required_prop_missing_from_serialize(%) if strict - assert_equal(:if, if_body.type) - if_strict_condition, if_strict_body, if_strict_else = if_body.children - assert_equal(s(:lvar, :strict), if_strict_condition) - assert_equal(:send, if_strict_body.type) - on_strict_receiver, on_strict_method, on_strict_arg = if_strict_body.children - assert_equal(nil, on_strict_receiver) - assert_equal(:required_prop_missing_from_serialize, on_strict_method) - assert_equal(:sym, on_strict_arg.type) - assert_equal(nil, if_strict_else) - end - - # h[%] = ... - assert_equal(:send, else_body.type) - receiver, method, h_key, h_val = else_body.children - assert_equal(s(:lvar, :h), receiver) - assert_equal(:[]=, method) - assert_equal(:str, h_key.type) - - validate_lack_of_side_effects(h_val, whitelisted_methods_for_serialize) - end - - private_class_method def self.validate_deserialize_hash_read(clause) - # val = hash[%s] - - assert_equal(:lvasgn, clause.type) - name, val = clause.children - assert_equal(:val, name) - assert_equal(:send, val.type) - receiver, method, arg = val.children - assert_equal(s(:lvar, :hash), receiver) - assert_equal(:[], method) - assert_equal(:str, arg.type) - end - - private_class_method def self.validate_deserialize_ivar_set(clause) - # %s = if val.nil? - # found -= 1 unless hash.key?(%s) - # %s - # else - # %s - # end - - assert_equal(:ivasgn, clause.type) - ivar_name, deser_val = clause.children - unless ivar_name.is_a?(Symbol) - raise ValidationError.new("Unexpected ivar: #{ivar_name}") - end - - assert_equal(:if, deser_val.type) - condition, if_body, else_body = deser_val.children - assert_equal(s(:send, s(:lvar, :val), :nil?), condition) - - assert_equal(:begin, if_body.type) - update_found, handle_nil = if_body.children - assert_equal(:if, update_found.type) - found_condition, found_if_body, found_else_body = update_found.children - assert_equal(:send, found_condition.type) - receiver, method, arg = found_condition.children - assert_equal(s(:lvar, :hash), receiver) - assert_equal(:key?, method) - assert_equal(:str, arg.type) - assert_equal(nil, found_if_body) - assert_equal(s(:op_asgn, s(:lvasgn, :found), :-, s(:int, 1)), found_else_body) - - validate_deserialize_handle_nil(handle_nil) - - if else_body.type == :kwbegin - rescue_expression, = else_body.children - assert_equal(:rescue, rescue_expression.type) - - try, rescue_body = rescue_expression.children - validate_lack_of_side_effects(try, whitelisted_methods_for_deserialize) - - 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)} - assert_equal(:lvasgn, assignment.type) - assert_equal([:e], assignment.children) - - deserialization_error, val_return = handler.children - - assert_equal(:send, deserialization_error.type) - 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)} - - validate_lack_of_side_effects(val_return, whitelisted_methods_for_deserialize) - else - validate_lack_of_side_effects(else_body, whitelisted_methods_for_deserialize) - end - end - - private_class_method def self.validate_deserialize_handle_nil(node) - case node.type - when :hash, :array, :str, :sym, :int, :float, :true, :false, :nil, :const # rubocop:disable Lint/BooleanSymbol - # Primitives and constants are safe - when :send - receiver, method, arg = node.children - if receiver.nil? - # required_prop_missing_from_deserialize(%) - assert_equal(:required_prop_missing_from_deserialize, method) - assert_equal(:sym, arg.type) - elsif receiver == self_class_decorator - # self.class.decorator.raise_nil_deserialize_error(%) - assert_equal(:raise_nil_deserialize_error, method) - assert_equal(:str, arg.type) - elsif method == :default - # self.class.decorator.props_with_defaults.fetch(%).default - assert_equal(:send, receiver.type) - inner_receiver, inner_method, inner_arg = receiver.children - assert_equal( - s(:send, self_class_decorator, :props_with_defaults), - inner_receiver, - ) - assert_equal(:fetch, inner_method) - assert_equal(:sym, inner_arg.type) - else - raise ValidationError.new("Unexpected receiver in nil handler: #{node.inspect}") - end - else - raise ValidationError.new("Unexpected nil handler: #{node.inspect}") - end - end - - private_class_method def self.self_class_decorator - @self_class_decorator ||= s(:send, s(:send, s(:self), :class), :decorator).freeze - end - - private_class_method def self.validate_lack_of_side_effects(node, whitelisted_methods_by_receiver_type) - case node.type - when :const - # This is ok, because we'll have validated what method has been called - # if applicable - when :hash, :array, :str, :sym, :int, :float, :true, :false, :nil, :self # rubocop:disable Lint/BooleanSymbol - # Primitives & self are ok - when :lvar, :arg, :ivar - # Reading local & instance variables & arguments is ok - 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} - when :send - # Sends are riskier so check a whitelist - receiver, method, *args = node.children - if receiver - if receiver.type == :send - key = receiver - else - key = receiver.type - validate_lack_of_side_effects(receiver, whitelisted_methods_by_receiver_type) - end - - if !whitelisted_methods_by_receiver_type[key]&.include?(method) - raise ValidationError.new("Unexpected method #{method} called on #{receiver.inspect}") - end - end - args.each do |arg| - validate_lack_of_side_effects(arg, whitelisted_methods_by_receiver_type) - end - else - raise ValidationError.new("Unexpected node type #{node.type}: #{node.inspect}") - end - end - - private_class_method def self.assert_equal(expected, actual) - if expected != actual - raise ValidationError.new("Expected #{expected}, got #{actual}") - end - end - - # Method calls generated by SerdeTransform - private_class_method def self.whitelisted_methods_for_serialize - @whitelisted_methods_for_serialize ||= { - lvar: %i{dup map transform_values transform_keys each_with_object nil? []= serialize}, - ivar: %i[dup map transform_values transform_keys each_with_object serialize], - const: %i[checked_serialize deep_clone_object], - } - end - - # Method calls generated by SerdeTransform - private_class_method def self.whitelisted_methods_for_deserialize - @whitelisted_methods_for_deserialize ||= { - lvar: %i{dup map transform_values transform_keys each_with_object nil? []= to_f}, - const: %i[deserialize from_hash deep_clone_object], - } - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb deleted file mode 100644 index 5c1acecb69..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb +++ /dev/null @@ -1,140 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props - - # Helper for generating methods that replace themselves with a specialized - # version on first use. The main use case is when we want to generate a - # method using the full set of props on a class; we can't do that during - # prop definition because we have no way of knowing whether we are defining - # the last prop. - # - # See go/M8yrvzX2 (Stripe-internal) for discussion of security considerations. - # In outline, while `class_eval` is a bit scary, we believe that as long as - # all inputs are defined in version control (and this is enforced by calling - # `disable_lazy_evaluation!` appropriately), risk isn't significantly higher - # than with build-time codegen. - module HasLazilySpecializedMethods - extend T::Sig - - class SourceEvaluationDisabled < RuntimeError - def initialize - super("Evaluation of lazily-defined methods is disabled") - end - end - - # Disable any future evaluation of lazily-defined methods. - # - # This is intended to be called after startup but before interacting with - # the outside world, to limit attack surface for our `class_eval` use. - # - # Note it does _not_ prevent explicit calls to `eagerly_define_lazy_methods!` - # from working. - sig {void} - def self.disable_lazy_evaluation! - @lazy_evaluation_disabled ||= true - end - - sig {returns(T::Boolean)} - def self.lazy_evaluation_enabled? - !defined?(@lazy_evaluation_disabled) || !@lazy_evaluation_disabled - end - - module DecoratorMethods - extend T::Sig - - 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)} - private def lazily_defined_vm_methods - @lazily_defined_vm_methods ||= {} - end - - sig {params(name: Symbol).void} - private def eval_lazily_defined_method!(name) - if !HasLazilySpecializedMethods.lazy_evaluation_enabled? - raise SourceEvaluationDisabled.new - end - - source = lazily_defined_methods.fetch(name).call - - cls = decorated_class - cls.class_eval(source.to_s) - cls.send(:private, name) - end - - sig {params(name: Symbol).void} - private def eval_lazily_defined_vm_method!(name) - if !HasLazilySpecializedMethods.lazy_evaluation_enabled? - raise SourceEvaluationDisabled.new - end - - lazily_defined_vm_methods.fetch(name).call - - cls = decorated_class - cls.send(:private, name) - end - - sig {params(name: Symbol, blk: T.proc.returns(String)).void} - private def enqueue_lazy_method_definition!(name, &blk) - lazily_defined_methods[name] = blk - - cls = decorated_class - if cls.method_defined?(name) - # Ruby does not emit "method redefined" warnings for aliased methods - # (more robust than undef_method that would create a small window in which the method doesn't exist) - cls.send(:alias_method, name, name) - end - cls.send(:define_method, name) do |*args| - self.class.decorator.send(:eval_lazily_defined_method!, name) - send(name, *args) - end - if cls.respond_to?(:ruby2_keywords, true) - cls.send(:ruby2_keywords, name) - end - cls.send(:private, name) - end - - sig {params(name: Symbol, blk: T.untyped).void} - private def enqueue_lazy_vm_method_definition!(name, &blk) - lazily_defined_vm_methods[name] = blk - - cls = decorated_class - cls.send(:define_method, name) do |*args| - self.class.decorator.send(:eval_lazily_defined_vm_method!, name) - send(name, *args) - end - if cls.respond_to?(:ruby2_keywords, true) - cls.send(:ruby2_keywords, name) - end - cls.send(:private, name) - end - - sig {void} - def eagerly_define_lazy_methods! - return if lazily_defined_methods.empty? - - source = lazily_defined_methods.values.map(&:call).map(&:to_s).join("\n\n") - - cls = decorated_class - cls.class_eval(source) - lazily_defined_methods.each_key {|name| cls.send(:private, name)} - lazily_defined_methods.clear - end - - 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.clear - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb deleted file mode 100644 index 4f482beac3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::Optional - include T::Props::Plugin -end - -############################################## - -# NB: This must stay in the same file where T::Props::Optional is defined due to -# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 -module T::Props::Optional::DecoratorMethods - extend T::Sig - - # Heads up! - # - # There are already too many ad-hoc options on the prop DSL. - # - # We have already done a lot of work to remove unnecessary and confusing - # options. If you're considering adding a new rule key, please come chat with - # the Sorbet team first, as we'd really like to learn more about how to best - # solve the problem you're encountering. - VALID_RULE_KEYS = { - default: true, - factory: true, - }.freeze - private_constant :VALID_RULE_KEYS - - DEFAULT_SETTER_RULE_KEY = :_t_props_private_apply_default - private_constant :DEFAULT_SETTER_RULE_KEY - - def valid_rule_key?(key) - super || VALID_RULE_KEYS[key] - end - - def prop_optional?(prop) - prop_rules(prop)[:fully_optional] - end - - def compute_derived_rules(rules) - rules[:fully_optional] = !T::Props::Utils.need_nil_write_check?(rules) - rules[:need_nil_read_check] = T::Props::Utils.need_nil_read_check?(rules) - end - - # checked(:never) - O(runtime object construction) - 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)} - attr_reader :props_without_defaults - - def add_prop_definition(prop, rules) - compute_derived_rules(rules) - - default_setter = T::Props::Private::ApplyDefault.for(decorated_class, rules) - if default_setter - @props_with_defaults ||= {} - @props_with_defaults[prop] = default_setter - props_without_defaults&.delete(prop) # Handle potential override - - rules[DEFAULT_SETTER_RULE_KEY] = default_setter - else - @props_without_defaults ||= {} - @props_without_defaults[prop] = rules.fetch(:setter_proc) - props_with_defaults&.delete(prop) # Handle potential override - end - - super - end - - def prop_validate_definition!(name, cls, rules, type) - result = super - - if rules.key?(:default) && rules.key?(:factory) - raise ArgumentError.new("Setting both :default and :factory is invalid. See: go/chalk-docs") - end - - result - end - - def has_default?(rules) - rules.include?(DEFAULT_SETTER_RULE_KEY) - end - - def get_default(rules, instance_class) - rules[DEFAULT_SETTER_RULE_KEY]&.default - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb deleted file mode 100644 index 1423c172ed..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::Plugin - include T::Props - extend T::Helpers - - module ClassMethods - def included(child) - super - child.plugin(self) - end - end - mixes_in_class_methods(ClassMethods) - - module Private - # These need to be non-instance methods so we can use them without prematurely creating the - # child decorator in `model_inherited` (see comments there for details). - # - # The dynamic constant access below forces this file to be `typed: false` - def self.apply_class_methods(plugin, target) - if plugin.const_defined?('ClassMethods') - # FIXME: This will break preloading, selective test execution, etc if `mod::ClassMethods` - # is ever defined in a separate file from `mod`. - target.extend(plugin::ClassMethods) - end - end - - def self.apply_decorator_methods(plugin, target) - if plugin.const_defined?('DecoratorMethods') - # FIXME: This will break preloading, selective test execution, etc if `mod::DecoratorMethods` - # is ever defined in a separate file from `mod`. - target.extend(plugin::DecoratorMethods) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb deleted file mode 100644 index e821cd3435..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb +++ /dev/null @@ -1,107 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Props::PrettyPrintable - include T::Props::Plugin - - # Return a string representation of this object and all of its props - def inspect - T.unsafe(T.cast(self, Object).class).decorator.inspect_instance(self) - end - - # Override the PP gem with something that's similar, but gives us a hook - # to do redaction - def pretty_inspect - T.unsafe(T.cast(self, Object).class).decorator.inspect_instance(self, multiline: true) - end - - module DecoratorMethods - extend T::Sig - - sig {params(key: Symbol).returns(T::Boolean).checked(:never)} - def valid_rule_key?(key) - super || key == :inspect - end - - sig do - params(instance: T::Props::PrettyPrintable, multiline: T::Boolean, indent: String) - .returns(String) - end - def inspect_instance(instance, multiline: false, indent: ' ') - components = - inspect_instance_components( - instance, - multiline: multiline, - indent: indent - ) - .reject(&:empty?) - - # Not using #<> here as that makes pry highlight these objects - # as if they were all comments, whereas this makes them look - # like the structured thing they are. - if multiline - "#{components[0]}:\n" + T.must(components[1..-1]).join("\n") - else - "<#{components.join(' ')}>" - end - end - - sig do - params(instance: T::Props::PrettyPrintable, multiline: T::Boolean, indent: String) - .returns(T::Array[String]) - end - private def inspect_instance_components(instance, multiline:, indent:) - pretty_props = T.unsafe(self).all_props.map do |prop| - [prop, inspect_prop_value(instance, prop, multiline: multiline, indent: indent)] - end - - joined_props = join_props_with_pretty_values( - pretty_props, - multiline: multiline, - indent: indent - ) - - [ - T.unsafe(self).decorated_class.to_s, - joined_props, - ] - end - - sig do - params(instance: T::Props::PrettyPrintable, prop: Symbol, multiline: T::Boolean, indent: String) - .returns(String) - .checked(:never) - end - private def inspect_prop_value(instance, prop, multiline:, indent:) - val = T.unsafe(self).get(instance, prop) - rules = T.unsafe(self).prop_rules(prop) - if (custom_inspect = rules[:inspect]) - if T::Utils.arity(custom_inspect) == 1 - custom_inspect.call(val) - else - custom_inspect.call(val, {multiline: multiline, indent: indent}) - end - elsif rules[:sensitivity] && !rules[:sensitivity].empty? && !val.nil? - "" - else - val.inspect - end - end - - sig do - params(pretty_kvs: T::Array[[Symbol, String]], multiline: T::Boolean, indent: String) - .returns(String) - end - private def join_props_with_pretty_values(pretty_kvs, multiline:, indent: ' ') - pairs = pretty_kvs - .sort_by {|k, _v| k.to_s} - .map {|k, v| "#{k}=#{v}"} - - if multiline - indent + pairs.join("\n#{indent}") - else - pairs.join(', ') - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb deleted file mode 100644 index b86f506f9a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb +++ /dev/null @@ -1,170 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - class ApplyDefault - extend T::Sig - extend T::Helpers - abstract! - - # checked(:never) - O(object construction x prop count) - 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)} - 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)} - def default; end - - # checked(:never) - O(object construction x prop count) - 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)} - def self.for(cls, rules) - accessor_key = rules.fetch(:accessor_key) - setter = rules.fetch(:setter_proc) - - if rules.key?(:factory) - ApplyDefaultFactory.new(cls, rules.fetch(:factory), accessor_key, setter) - elsif rules.key?(:default) - default = rules.fetch(:default) - case default - when *NO_CLONE_TYPES - return ApplyPrimitiveDefault.new(default, accessor_key, setter) - when String - if default.frozen? - return ApplyPrimitiveDefault.new(default, accessor_key, setter) - end - when Array - if default.empty? && default.class == Array - return ApplyEmptyArrayDefault.new(accessor_key, setter) - end - when Hash - if default.empty? && default.default.nil? && T.unsafe(default).default_proc.nil? && default.class == Hash - return ApplyEmptyHashDefault.new(accessor_key, setter) - end - end - - ApplyComplexDefault.new(default, accessor_key, setter) - else - nil - end - end - end - - class ApplyFixedDefault < ApplyDefault - abstract! - - # checked(:never) - We do this with `T.let` instead - 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. - # - # :( - # - # setter_proc.call(default) - @default = T.let(default, BasicObject) - super(accessor_key, setter_proc) - end - - # checked(:never) - O(object construction x prop count) - 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 - end - - class ApplyPrimitiveDefault < ApplyFixedDefault - # checked(:never) - O(object construction x prop count) - 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)} - def default - T::Props::Utils.deep_clone_object(@default) - end - end - - # Special case since it's so common, and a literal `[]` is meaningfully - # faster than falling back to ApplyComplexDefault or even calling - # `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)} - 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)} - def default - [] - end - end - - # Special case since it's so common, and a literal `{}` is meaningfully - # faster than falling back to ApplyComplexDefault or even calling - # `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)} - 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)} - def default - {} - end - end - - class ApplyDefaultFactory < ApplyDefault - # checked(:never) - We do this with `T.let` instead - sig do - params( - cls: Module, - factory: T.any(Proc, Method), - accessor_key: Symbol, - setter_proc: SetterFactory::SetterProc, - ) - .void - .checked(:never) - end - def initialize(cls, factory, accessor_key, setter_proc) - @class = T.let(cls, Module) - @factory = T.let(factory, T.any(Proc, Method)) - super(accessor_key, setter_proc) - end - - # checked(:never) - O(object construction x prop count) - 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 - instance.instance_exec(default, &@setter_proc) - end - - # checked(:never) - O(object construction x prop count) - sig {override.returns(T.untyped).checked(:never)} - def default - @class.class_exec(&@factory) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb deleted file mode 100644 index 2393e1a284..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb +++ /dev/null @@ -1,160 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - - # Generates a specialized `deserialize` implementation for a subclass of - # T::Props::Serializable. - # - # The basic idea is that we analyze the props and for each prop, generate - # the simplest possible logic as a block of Ruby source, so that we don't - # pay the cost of supporting types like T:::Hash[CustomType, SubstructType] - # when deserializing a simple Integer. Then we join those together, - # with a little shared logic to be able to detect when we get input keys - # that don't match any prop. - module DeserializerGenerator - extend T::Sig - - # Generate a method that takes a T::Hash[String, T.untyped] representing - # serialized props, sets instance variables for each prop found in the - # input, and returns the count of we props set (which we can use to check - # for unexpected input keys with minimal effect on the fast path). - sig do - params( - props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]], - defaults: T::Hash[Symbol, T::Props::Private::ApplyDefault], - ) - .returns(String) - .checked(:never) - end - def self.generate(props, defaults) - 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 - # error message, but we double check here to prevent a refactoring - # from introducing a security vulnerability. - raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s) - - hash_key = rules.fetch(:serialized_form) - raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key) - - ivar_name = rules.fetch(:accessor_key).to_s - raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1]) - - transformation = SerdeTransform.generate( - T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)), - SerdeTransform::Mode::DESERIALIZE, - 'val' - ) - transformed_val = if transformation - # Rescuing exactly NoMethodError is intended as a temporary hack - # to preserve the semantics from before codegen. More generally - # we are inconsistent about typechecking on deser and need to decide - # our strategy here. - <<~RUBY - begin - #{transformation} - rescue NoMethodError => e - raise_deserialization_error( - #{prop.inspect}, - val, - e, - ) - val - end - RUBY - else - 'val' - end - - nil_handler = generate_nil_handler( - prop: prop, - serialized_form: hash_key, - default: defaults[prop], - nilable_type: T::Props::Utils.optional_prop?(rules), - raise_on_nil_write: !!rules[:raise_on_nil_write], - ) - - <<~RUBY - val = hash[#{hash_key.inspect}] - #{ivar_name} = if val.nil? - found -= 1 unless hash.key?(#{hash_key.inspect}) - #{nil_handler} - else - #{transformed_val} - end - RUBY - end - - <<~RUBY - def __t_props_generated_deserialize(hash) - found = #{stored_props.size} - #{parts.join("\n\n")} - found - end - RUBY - end - - # This is very similar to what we do in ApplyDefault, but has a few - # key differences that mean we don't just re-use the code: - # - # 1. Where the logic in construction is that we generate a default - # if & only if the prop key isn't present in the input, here we'll - # generate a default even to override an explicit nil, but only - # if the prop is actually required. - # 2. Since we're generating raw Ruby source, we can remove a layer - # of indirection for marginally better performance; this seems worth - # it for the common cases of literals and empty arrays/hashes. - # 3. We need to care about the distinction between `raise_on_nil_write` - # and actually non-nilable, where new-instance construction doesn't. - # - # So we fall back to ApplyDefault only when one of the cases just - # mentioned doesn't apply. - sig do - params( - prop: Symbol, - serialized_form: String, - default: T.nilable(ApplyDefault), - nilable_type: T::Boolean, - raise_on_nil_write: T::Boolean, - ) - .returns(String) - .checked(:never) - end - private_class_method def self.generate_nil_handler( - prop:, - serialized_form:, - default:, - nilable_type:, - raise_on_nil_write: - ) - if !nilable_type - case default - when NilClass - "self.class.decorator.raise_nil_deserialize_error(#{serialized_form.inspect})" - when ApplyPrimitiveDefault - literal = default.default - case literal - when String, Integer, Symbol, Float, TrueClass, FalseClass, NilClass - literal.inspect - else - "self.class.decorator.props_with_defaults.fetch(#{prop.inspect}).default" - end - when ApplyEmptyArrayDefault - '[]' - when ApplyEmptyHashDefault - '{}' - else - "self.class.decorator.props_with_defaults.fetch(#{prop.inspect}).default" - end - elsif raise_on_nil_write - "required_prop_missing_from_deserialize(#{prop.inspect})" - else - 'nil' - end - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb deleted file mode 100644 index 2ccd574118..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props - module Private - module Parse - def parse(source) - @current_ruby ||= require_parser(:CurrentRuby) - @current_ruby.parse(source) - end - - def s(type, *children) - @node ||= require_parser(:AST, :Node) - @node.new(type, children) - end - - private def require_parser(*constants) - # This is an optional dependency for sorbet-runtime in general, - # but is required here - require 'parser/current' - - # Hack to work around the static checker thinking the constant is - # undefined - cls = Kernel.const_get(:Parser, true) - while (const = constants.shift) - cls = cls.const_get(const, false) - end - cls - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb deleted file mode 100644 index e0b37a376d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb +++ /dev/null @@ -1,186 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - module SerdeTransform - extend T::Sig - - class Serialize; end - private_constant :Serialize - class Deserialize; end - private_constant :Deserialize - ModeType = T.type_alias {T.any(Serialize, Deserialize)} - private_constant :ModeType - - module Mode - SERIALIZE = T.let(Serialize.new.freeze, Serialize) - DESERIALIZE = T.let(Deserialize.new.freeze, Deserialize) - end - - NO_TRANSFORM_TYPES = T.let( - [TrueClass, FalseClass, NilClass, Symbol, String].freeze, - T::Array[Module], - ) - private_constant :NO_TRANSFORM_TYPES - - sig do - params( - type: T::Types::Base, - mode: ModeType, - varname: String, - ) - .returns(T.nilable(String)) - .checked(:never) - end - def self.generate(type, mode, varname) - case type - when T::Types::TypedArray - inner = generate(type.type, mode, 'v') - if inner.nil? - "#{varname}.dup" - else - "#{varname}.map {|v| #{inner}}" - end - when T::Types::TypedSet - inner = generate(type.type, mode, 'v') - if inner.nil? - "#{varname}.dup" - else - "Set.new(#{varname}) {|v| #{inner}}" - end - when T::Types::TypedHash - keys = generate(type.keys, mode, 'k') - values = generate(type.values, mode, 'v') - if keys && values - "#{varname}.each_with_object({}) {|(k,v),h| h[#{keys}] = #{values}}" - elsif keys - "#{varname}.transform_keys {|k| #{keys}}" - elsif values - "#{varname}.transform_values {|v| #{values}}" - else - "#{varname}.dup" - end - when T::Types::Simple - raw = type.raw_type - if NO_TRANSFORM_TYPES.any? {|cls| raw <= cls} - nil - elsif raw <= Float - case mode - when Deserialize then "#{varname}.to_f" - when Serialize then nil - else T.absurd(mode) - end - elsif raw <= Numeric - nil - elsif raw < T::Props::Serializable - handle_serializable_subtype(varname, raw, mode) - elsif raw.singleton_class < T::Props::CustomType - handle_custom_type(varname, T.unsafe(raw), mode) - elsif T::Configuration.scalar_types.include?(raw.name) - # It's a bit of a hack that this is separate from NO_TRANSFORM_TYPES - # and doesn't check inheritance (like `T::Props::CustomType.scalar_type?` - # does), but it covers the main use case (pay-server's custom `Boolean` - # module) without either requiring `T::Configuration.scalar_types` to - # accept modules instead of strings (which produces load-order issues - # and subtle behavior changes) or eating the performance cost of doing - # an inheritance check by manually crawling a class hierarchy and doing - # string comparisons. - nil - else - "T::Props::Utils.deep_clone_object(#{varname})" - end - when T::Types::Union - non_nil_type = T::Utils.unwrap_nilable(type) - if non_nil_type - inner = generate(non_nil_type, mode, varname) - if inner.nil? - nil - else - "#{varname}.nil? ? nil : #{inner}" - end - elsif type.types.all? {|t| generate(t, mode, varname).nil?} - # Handle, e.g., T::Boolean - nil - else - # We currently deep_clone_object if the type was T.any(Integer, Float). - # When we get better support for union types (maybe this specific - # union type, because it would be a replacement for - # Chalk::ODM::DeprecatedNumemric), we could opt to special case - # this union to have no specific serde transform (the only reason - # why Float has a special case is because round tripping through - # JSON might normalize Floats to Integers) - "T::Props::Utils.deep_clone_object(#{varname})" - end - when T::Types::Intersection - dynamic_fallback = "T::Props::Utils.deep_clone_object(#{varname})" - - # Transformations for any members of the intersection type where we - # know what we need to do and did not have to fall back to the - # dynamic deep clone method. - # - # 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} - .uniq - - if inner_known.size != 1 - # If there were no cases where we could tell what we need to do, - # e.g. if this is `T.all(SomethingWeird, WhoKnows)`, just use the - # dynamic fallback. - # - # If there were multiple cases and they weren't consistent, e.g. - # if this is `T.all(String, T::Array[Integer])`, the type is probably - # bogus/uninhabited, but use the dynamic fallback because we still - # don't have a better option, and this isn't the place to raise that - # error. - dynamic_fallback - else - # This is probably something like `T.all(String, SomeMarker)` or - # `T.all(SomeEnum, T.deprecated_enum(SomeEnum::FOO))` and we should - # treat it like String or SomeEnum even if we don't know what to do - # with the rest of the type. - inner_known.first - end - when T::Types::Enum - generate(T::Utils.lift_enum(type), mode, varname) - else - "T::Props::Utils.deep_clone_object(#{varname})" - end - end - - 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 - "#{varname}.serialize(strict)" - when Deserialize - type_name = T.must(module_name(type)) - "#{type_name}.from_hash(#{varname})" - else - T.absurd(mode) - end - end - - 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 - "T::Props::CustomType.checked_serialize(#{varname})" - when Deserialize - type_name = T.must(module_name(type)) - "#{type_name}.deserialize(#{varname})" - else - T.absurd(mode) - end - end - - 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 - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb deleted file mode 100644 index 0d49a46e0f..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - - # Generates a specialized `serialize` implementation for a subclass of - # T::Props::Serializable. - # - # The basic idea is that we analyze the props and for each prop, generate - # the simplest possible logic as a block of Ruby source, so that we don't - # pay the cost of supporting types like T:::Hash[CustomType, SubstructType] - # when serializing a simple Integer. Then we join those together, - # with a little shared logic to be able to detect when we get input keys - # that don't match any prop. - module SerializerGenerator - extend T::Sig - - sig do - params( - props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]], - ) - .returns(String) - .checked(:never) - end - def self.generate(props) - 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 - # error message, but we double check here to prevent a refactoring - # from introducing a security vulnerability. - raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s) - - hash_key = rules.fetch(:serialized_form) - raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key) - - ivar_name = rules.fetch(:accessor_key).to_s - raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1]) - - transformed_val = SerdeTransform.generate( - T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)), - SerdeTransform::Mode::SERIALIZE, - ivar_name - ) || ivar_name - - nil_asserter = - if rules[:fully_optional] - '' - else - "required_prop_missing_from_serialize(#{prop.inspect}) if strict" - end - - # Don't serialize values that are nil to save space (both the - # nil value itself and the field name in the serialized BSON - # document) - <<~RUBY - if #{ivar_name}.nil? - #{nil_asserter} - else - h[#{hash_key.inspect}] = #{transformed_val} - end - RUBY - end - - <<~RUBY - def __t_props_generated_serialize(strict) - h = {} - #{parts.join("\n\n")} - h - end - RUBY - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb deleted file mode 100644 index 00c76ed1e7..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb +++ /dev/null @@ -1,197 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - module SetterFactory - extend T::Sig - - SetterProc = 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( - klass: T.all(Module, T::Props::ClassMethods), - prop: Symbol, - rules: T::Hash[Symbol, T.untyped] - ) - .returns(SetterProc) - .checked(:never) - end - def self.build_setter_proc(klass, prop, rules) - # Our nil check works differently than a simple T.nilable for various - # reasons (including the `raise_on_nil_write` setting and the existence - # of defaults & factories), so unwrap any T.nilable and do a check - # manually. - non_nil_type = T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)) - accessor_key = rules.fetch(:accessor_key) - validate = rules[:setter_validate] - - # It seems like a bug that this affects the behavior of setters, but - # some existing code relies on this behavior - has_explicit_nil_default = rules.key?(:default) && rules.fetch(:default).nil? - - # Use separate methods in order to ensure that we only close over necessary - # variables - if !T::Props::Utils.need_nil_write_check?(rules) || has_explicit_nil_default - if validate.nil? && non_nil_type.is_a?(T::Types::Simple) - simple_nilable_proc(prop, accessor_key, non_nil_type.raw_type, klass) - else - nilable_proc(prop, accessor_key, non_nil_type, klass, validate) - end - else - if validate.nil? && non_nil_type.is_a?(T::Types::Simple) - simple_non_nil_proc(prop, accessor_key, non_nil_type.raw_type, klass) - else - non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) - end - end - end - - sig do - params( - prop: Symbol, - accessor_key: Symbol, - non_nil_type: Module, - klass: T.all(Module, T::Props::ClassMethods), - ) - .returns(SetterProc) - end - private_class_method def self.simple_non_nil_proc(prop, accessor_key, non_nil_type, klass) - proc do |val| - unless val.is_a?(non_nil_type) - T::Props::Private::SetterFactory.raise_pretty_error( - klass, - prop, - T::Utils.coerce(non_nil_type), - val, - ) - end - instance_variable_set(accessor_key, val) - end - end - - sig do - params( - prop: Symbol, - accessor_key: Symbol, - non_nil_type: T::Types::Base, - klass: T.all(Module, T::Props::ClassMethods), - validate: T.nilable(ValidateProc) - ) - .returns(SetterProc) - end - private_class_method def self.non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) - proc do |val| - # this use of recursively_valid? is intentional: unlike for - # methods, we want to make sure data at the 'edge' - # (e.g. models that go into databases or structs serialized - # from disk) are correct, so we use more thorough runtime - # checks there - if non_nil_type.recursively_valid?(val) - validate&.call(prop, val) - else - T::Props::Private::SetterFactory.raise_pretty_error( - klass, - prop, - non_nil_type, - val, - ) - end - instance_variable_set(accessor_key, val) - end - end - - sig do - params( - prop: Symbol, - accessor_key: Symbol, - non_nil_type: Module, - klass: T.all(Module, T::Props::ClassMethods), - ) - .returns(SetterProc) - end - private_class_method def self.simple_nilable_proc(prop, accessor_key, non_nil_type, klass) - proc do |val| - if val.nil? - instance_variable_set(accessor_key, nil) - elsif val.is_a?(non_nil_type) - instance_variable_set(accessor_key, val) - else - T::Props::Private::SetterFactory.raise_pretty_error( - klass, - prop, - T::Utils.coerce(non_nil_type), - val, - ) - instance_variable_set(accessor_key, val) - end - end - end - - sig do - params( - prop: Symbol, - accessor_key: Symbol, - non_nil_type: T::Types::Base, - klass: T.all(Module, T::Props::ClassMethods), - validate: T.nilable(ValidateProc), - ) - .returns(SetterProc) - end - private_class_method def self.nilable_proc(prop, accessor_key, non_nil_type, klass, validate) - proc do |val| - if val.nil? - instance_variable_set(accessor_key, nil) - # this use of recursively_valid? is intentional: unlike for - # methods, we want to make sure data at the 'edge' - # (e.g. models that go into databases or structs serialized - # from disk) are correct, so we use more thorough runtime - # checks there - elsif non_nil_type.recursively_valid?(val) - validate&.call(prop, val) - instance_variable_set(accessor_key, val) - else - T::Props::Private::SetterFactory.raise_pretty_error( - klass, - prop, - non_nil_type, - val, - ) - instance_variable_set(accessor_key, val) - end - end - end - - sig do - params( - klass: T.all(Module, T::Props::ClassMethods), - prop: Symbol, - type: T.any(T::Types::Base, Module), - val: T.untyped, - ) - .void - end - def self.raise_pretty_error(klass, prop, type, val) - 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')} - if caller_loc - pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" - end - - T::Configuration.call_validation_error_handler( - nil, - message: base_message, - pretty_message: pretty_message, - kind: 'Parameter', - name: prop, - type: type, - value: val, - location: caller_loc, - ) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb deleted file mode 100644 index 2e2ea1b749..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb +++ /dev/null @@ -1,374 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::Serializable - include T::Props::Plugin - # Required because we have special handling for `optional: false` - include T::Props::Optional - # Required because we have special handling for extra_props - include T::Props::PrettyPrintable - - # Serializes this object to a hash, suitable for conversion to - # JSON/BSON. - # - # @param strict [T::Boolean] (true) If false, do not raise an - # exception if this object has mandatory props with missing - # values. - # @return [Hash] A serialization of this object. - def serialize(strict=true) - begin - h = __t_props_generated_serialize(strict) - rescue => e - msg = self.class.decorator.message_with_generated_source_context( - e, - :__t_props_generated_serialize, - :generate_serialize_source - ) - if msg - begin - raise e.class.new(msg) - rescue ArgumentError - raise TypeError.new(msg) - end - else - raise - end - end - - h.merge!(@_extra_props) if defined?(@_extra_props) - h - end - - private def __t_props_generated_serialize(strict) - # No-op; will be overridden if there are any props. - # - # To see the definition for class `Foo`, run `Foo.decorator.send(:generate_serialize_source)` - {} - end - - # Populates the property values on this object with the values - # from a hash. In general, prefer to use {.from_hash} to construct - # a new instance, instead of loading into an existing instance. - # - # @param hash [Hash] The hash to take property - # values from. - # @param strict [T::Boolean] (false) If true, raise an exception if - # the hash contains keys that do not correspond to any known - # props on this instance. - # @return [void] - def deserialize(hash, strict=false) - begin - hash_keys_matching_props = __t_props_generated_deserialize(hash) - rescue => e - msg = self.class.decorator.message_with_generated_source_context( - e, - :__t_props_generated_deserialize, - :generate_deserialize_source - ) - if msg - begin - raise e.class.new(msg) - rescue ArgumentError - raise TypeError.new(msg) - end - else - raise - end - end - - 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` could still be empty here if the input matches a `dont_store` prop; - # historically, we just ignore those - if !extra.empty? - if strict - raise "Unknown properties for #{self.class.name}: #{extra.keys.inspect}" - else - @_extra_props = extra - end - end - end - end - - private def __t_props_generated_deserialize(hash) - # No-op; will be overridden if there are any props. - # - # To see the definition for class `Foo`, run `Foo.decorator.send(:generate_deserialize_source)` - 0 - end - - # with() will clone the old object to the new object and merge the specified props to the new object. - def with(changed_props) - with_existing_hash(changed_props, existing_hash: self.serialize) - end - - private def recursive_stringify_keys(obj) - if obj.is_a?(Hash) - new_obj = obj.class.new - obj.each do |k, v| - new_obj[k.to_s] = recursive_stringify_keys(v) - end - elsif obj.is_a?(Array) - new_obj = obj.map {|v| recursive_stringify_keys(v)} - else - new_obj = obj - end - new_obj - end - - private def with_existing_hash(changed_props, existing_hash:) - serialized = existing_hash - new_val = self.class.from_hash(serialized.merge(recursive_stringify_keys(changed_props))) - old_extra = self.instance_variable_get(:@_extra_props) if self.instance_variable_defined?(:@_extra_props) - new_extra = new_val.instance_variable_get(:@_extra_props) if new_val.instance_variable_defined?(:@_extra_props) - if old_extra != new_extra - difference = - if old_extra - new_extra.reject {|k, v| old_extra[k] == v} - else - new_extra - end - raise ArgumentError.new("Unexpected arguments: input(#{changed_props}), unexpected(#{difference})") - end - new_val - end - - # Asserts if this property is missing during strict serialize - private def required_prop_missing_from_serialize(prop) - if defined?(@_required_props_missing_from_deserialize) && - @_required_props_missing_from_deserialize&.include?(prop) - # If the prop was already missing during deserialization, that means the application - # code already had to deal with a nil value, which means we wouldn't be accomplishing - # much by raising here (other than causing an unnecessary breakage). - T::Configuration.log_info_handler( - "chalk-odm: missing required property in serialize", - prop: prop, class: self.class.name, id: self.class.decorator.get_id(self) - ) - else - raise TypeError.new("#{self.class.name}.#{prop} not set for non-optional prop") - end - end - - # Marks this property as missing during deserialize - private def required_prop_missing_from_deserialize(prop) - @_required_props_missing_from_deserialize ||= Set[] - @_required_props_missing_from_deserialize << prop - nil - end - - private def raise_deserialization_error(prop_name, value, orig_error) - T::Configuration.soft_assert_handler( - 'Deserialization error (probably unexpected stored type)', - storytime: { - klass: self.class, - prop: prop_name, - value: value, - error: orig_error.message, - notify: 'djudd' - } - ) - end -end - -############################################## - -# NB: This must stay in the same file where T::Props::Serializable is defined due to -# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 -module T::Props::Serializable::DecoratorMethods - include T::Props::HasLazilySpecializedMethods::DecoratorMethods - - # Heads up! - # - # There are already too many ad-hoc options on the prop DSL. - # - # We have already done a lot of work to remove unnecessary and confusing - # options. If you're considering adding a new rule key, please come chat with - # the Sorbet team first, as we'd really like to learn more about how to best - # solve the problem you're encountering. - VALID_RULE_KEYS = {dont_store: true, name: true, raise_on_nil_write: true}.freeze - private_constant :VALID_RULE_KEYS - - def valid_rule_key?(key) - super || VALID_RULE_KEYS[key] - end - - def required_props - @class.props.select {|_, v| T::Props::Utils.required_prop?(v)}.keys - end - - def prop_dont_store?(prop) - prop_rules(prop)[:dont_store] - end - def prop_by_serialized_forms - @class.prop_by_serialized_forms - end - - def from_hash(hash, strict=false) - raise ArgumentError.new("#{hash.inspect} provided to from_hash") if !(hash && hash.is_a?(Hash)) - - i = @class.allocate - i.deserialize(hash, strict) - - i - end - - def prop_serialized_form(prop) - prop_rules(prop)[:serialized_form] - end - - def serialized_form_prop(serialized_form) - prop_by_serialized_forms[serialized_form.to_s] || raise("No such serialized form: #{serialized_form.inspect}") - end - - def add_prop_definition(prop, rules) - rules[:serialized_form] = rules.fetch(:name, prop.to_s) - res = super - prop_by_serialized_forms[rules[: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} - else - 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 - - private def generate_serialize_source - T::Props::Private::SerializerGenerator.generate(props) - end - - private def generate_deserialize_source - T::Props::Private::DeserializerGenerator.generate( - props, - props_with_defaults || {}, - ) - end - - private def generate_serialize2 - T::Props::Private::SerializerGenerator.generate2(decorated_class, props) - end - - private def generate_deserialize2 - T::Props::Private::DeserializerGenerator.generate2( - decorated_class, - props, - props_with_defaults || {}, - ) - end - - def message_with_generated_source_context(error, generated_method, generate_source_method) - line_label = error.backtrace.find {|l| l.end_with?("in `#{generated_method}'")} - return unless line_label - - line_num = line_label.split(':')[1]&.to_i - return unless line_num - - source_lines = self.send(generate_source_method).split("\n") - previous_blank = source_lines[0...line_num].rindex(&:empty?) || 0 - next_blank = line_num + (source_lines[line_num..-1]&.find_index(&:empty?) || 0) - context = " #{source_lines[(previous_blank + 1)...next_blank].join("\n ")}" - <<~MSG - Error in #{decorated_class.name}##{generated_method}: #{error.message} - at line #{line_num - previous_blank - 1} in: - #{context} - MSG - end - - def raise_nil_deserialize_error(hkey) - msg = "Tried to deserialize a required prop from a nil value. It's "\ - "possible that a nil value exists in the database, so you should "\ - "provide a `default: or factory:` for this prop (see go/optional "\ - "for more details). If this is already the case, you probably "\ - "omitted a required prop from the `fields:` option when doing a "\ - "partial load." - storytime = {prop: hkey, klass: decorated_class.name} - - # Notify the model owner if it exists, and always notify the API owner. - begin - if T::Configuration.class_owner_finder && (owner = T::Configuration.class_owner_finder.call(decorated_class)) - T::Configuration.hard_assert_handler( - msg, - storytime: storytime, - project: owner - ) - end - ensure - T::Configuration.hard_assert_handler(msg, storytime: storytime) - end - end - - def prop_validate_definition!(name, cls, rules, type) - result = super - - if (rules_name = rules[:name]) - unless rules_name.is_a?(String) - raise ArgumentError.new("Invalid name in prop #{@class.name}.#{name}: #{rules_name.inspect}") - end - - validate_prop_name(rules_name) - end - - if !rules[:raise_on_nil_write].nil? && rules[:raise_on_nil_write] != true - raise ArgumentError.new("The value of `raise_on_nil_write` if specified must be `true` (given: #{rules[:raise_on_nil_write]}).") - end - - result - end - - def get_id(instance) - prop = prop_by_serialized_forms['_id'] - if prop - get(instance, prop) - else - nil - end - end - - EMPTY_EXTRA_PROPS = {}.freeze - private_constant :EMPTY_EXTRA_PROPS - - def extra_props(instance) - if instance.instance_variable_defined?(:@_extra_props) - instance.instance_variable_get(:@_extra_props) || EMPTY_EXTRA_PROPS - else - EMPTY_EXTRA_PROPS - end - end - - # overrides T::Props::PrettyPrintable - private def inspect_instance_components(instance, multiline:, indent:) - if (extra_props = extra_props(instance)) && !extra_props.empty? - pretty_kvs = extra_props.map {|k, v| [k.to_sym, v.inspect]} - extra = join_props_with_pretty_values(pretty_kvs, multiline: false) - super + ["@_extra_props=<#{extra}>"] - else - super - end - end -end - -############################################## - -# NB: This must stay in the same file where T::Props::Serializable is defined due to -# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 -module T::Props::Serializable::ClassMethods - def prop_by_serialized_forms - @prop_by_serialized_forms ||= {} - end - - # Allocate a new instance and call {#deserialize} to load a new - # object from a hash. - # @return [Serializable] - def from_hash(hash, strict=false) - self.decorator.from_hash(hash, strict) - end - - # Equivalent to {.from_hash} with `strict` set to true. - # @return [Serializable] - def from_hash!(hash) - self.decorator.from_hash(hash, true) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb deleted file mode 100644 index ae3557783d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb +++ /dev/null @@ -1,111 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::TypeValidation - include T::Props::Plugin - - BANNED_TYPES = [Object, BasicObject, Kernel].freeze - - class UnderspecifiedType < ArgumentError; end - - module DecoratorMethods - extend T::Sig - - sig {params(key: Symbol).returns(T::Boolean).checked(:never)} - def valid_rule_key?(key) - super || key == :DEPRECATED_underspecified_type - end - - sig do - params( - name: T.any(Symbol, String), - _cls: Module, - rules: T::Hash[Symbol, T.untyped], - type: T.any(T::Types::Base, Module) - ) - .void - end - def prop_validate_definition!(name, _cls, rules, type) - super - - if !rules[:DEPRECATED_underspecified_type] - validate_type(type, field_name: name) - elsif rules[:DEPRECATED_underspecified_type] && find_invalid_subtype(type).nil? - raise ArgumentError.new("DEPRECATED_underspecified_type set unnecessarily for #{@class.name}.#{name} - #{type} is a valid type") - end - end - - sig do - params( - type: T::Types::Base, - field_name: T.any(Symbol, String), - ) - .void - end - private def validate_type(type, field_name:) - if (invalid_subtype = find_invalid_subtype(type)) - raise UnderspecifiedType.new(type_error_message(invalid_subtype, field_name, type)) - end - end - - # Returns an invalid type, if any, found in the given top-level type. - # This might be the type itself, if it is e.g. "Object", or might be - # a subtype like the type of the values of a typed hash. - # - # 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)} - 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 - 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 - 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 - if invalid.length == type.types.length - invalid.first - else - nil - end - when T::Types::Enum, T::Types::ClassOf - nil - when T::Private::Types::TypeAlias - find_invalid_subtype(type.aliased_type) - when T::Types::Simple - # TODO Could we manage to define a whitelist, consisting of something - # like primitives, subdocs, DataInterfaces, and collections/enums/unions - # thereof? - if BANNED_TYPES.include?(type.raw_type) - type - else - nil - end - else - type - end - end - - sig do - params( - type: T::Types::Base, - field_name: T.any(Symbol, String), - orig_type: T::Types::Base, - ) - .returns(String) - end - private def type_error_message(type, field_name, orig_type) - msg_prefix = "#{@class.name}.#{field_name}: #{orig_type} is invalid in prop definition" - if type == orig_type - "#{msg_prefix}. Please choose a more specific type (T.untyped and ~equivalents like Object are banned)." - else - "#{msg_prefix}. Please choose a subtype more specific than #{type} (T.untyped and ~equivalents like Object are banned)." - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb deleted file mode 100644 index 33d1abadce..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Props::Utils - # Deep copy an object. The object must consist of Ruby primitive - # types and Hashes and Arrays. - def self.deep_clone_object(what, freeze: false) - result = case what - when true - true - when false - false - when Symbol, NilClass, Numeric - what - when Array - what.map {|v| deep_clone_object(v, freeze: freeze)} - when Hash - h = what.class.new - what.each do |k, v| - k.freeze if freeze - h[k] = deep_clone_object(v, freeze: freeze) - end - h - when Regexp - what.dup - when T::Enum - what - else - what.clone - end - freeze ? result.freeze : result - end - - # The prop_rules indicate whether we should check for reading a nil value for the prop/field. - # This is mostly for the compatibility check that we allow existing documents carry some nil prop/field. - def self.need_nil_read_check?(prop_rules) - # . :on_load allows nil read, but we need to check for the read for future writes - prop_rules[:optional] == :on_load || prop_rules[:raise_on_nil_write] - end - - # The prop_rules indicate whether we should check for writing a nil value for the prop/field. - def self.need_nil_write_check?(prop_rules) - need_nil_read_check?(prop_rules) || T::Props::Utils.required_prop?(prop_rules) - end - - def self.required_prop?(prop_rules) - # Clients should never reference :_tnilable as the implementation can change. - !prop_rules[:_tnilable] - end - - def self.optional_prop?(prop_rules) - # Clients should never reference :_tnilable as the implementation can change. - !!prop_rules[:_tnilable] - end - - def self.merge_serialized_optional_rule(prop_rules) - {'_tnilable' => true}.merge(prop_rules.merge('_tnilable' => true)) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb deleted file mode 100644 index 3ffe1be695..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::WeakConstructor - include T::Props::Optional - extend T::Sig - - # checked(:never) - O(runtime object construction) - sig {params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never)} - def initialize(hash={}) - decorator = self.class.decorator - - hash_keys_matching_props = decorator.construct_props_with_defaults(self, hash) + - decorator.construct_props_without_defaults(self, hash) - - if hash_keys_matching_props < hash.size - raise ArgumentError.new("#{self.class}: Unrecognized properties: #{(hash.keys - decorator.props.keys).join(', ')}") - end - end -end - -module T::Props::WeakConstructor::DecoratorMethods - extend T::Sig - - # Set values for all props that have no defaults. Ignore any not present. - # - # @return [Integer] A count of props that we successfully initialized (which - # 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)} - 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. - result = 0 - props_without_defaults&.each_pair do |p, setter_proc| - if hash.key?(p) - instance.instance_exec(hash[p], &setter_proc) - result += 1 - end - end - result - end - - # Set values for all props that have defaults. Use the default if and only if - # the prop key isn't in the input. - # - # @return [Integer] A count of props that we successfully initialized (which - # 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)} - 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. - result = 0 - props_with_defaults&.each_pair do |p, default_struct| - if hash.key?(p) - instance.instance_exec(hash[p], &default_struct.setter_proc) - result += 1 - else - default_struct.set_default(instance) - end - end - result - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb deleted file mode 100644 index 3112adf861..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -# Used as a mixin to any class so that you can call `sig`. -# Docs at https://sorbet.org/docs/sigs -module T::Sig - module WithoutRuntime - # 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. - def self.sig(arg0=nil, &blk); end - - original_verbose = $VERBOSE - $VERBOSE = false - - # 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} - def self.sig(arg0=nil, &blk); end # rubocop:disable Lint/DuplicateMethods - - $VERBOSE = original_verbose - end - - # 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} - def sig(arg0=nil, &blk) - T::Private::Methods.declare_sig(self, Kernel.caller_locations(1, 1)&.first, arg0, &blk) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb deleted file mode 100644 index 5f35d1f81f..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# typed: true - -class T::InexactStruct - include T::Props - include T::Props::Serializable - include T::Props::Constructor -end - -class T::Struct < T::InexactStruct - def self.inherited(subclass) - super(subclass) - T::Private::ClassUtils.replace_method(subclass.singleton_class, :inherited) do |s| - super(s) - raise "#{self.name} is a subclass of T::Struct and cannot be subclassed" - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb deleted file mode 100644 index 059956a68d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Modeling AttachedClass properly at runtime would require additional - # tracking, so at runtime we permit all values and rely on the static checker. - # As AttachedClass is modeled statically as a type member on every singleton - # class, this is consistent with the runtime behavior for all type members. - class AttachedClassType < Base - - def initialize(); end - - # overrides Base - def name - "T.attached_class" - end - - # overrides Base - def valid?(obj) - true - end - - # overrides Base - private def subtype_of_single?(other) - case other - when AttachedClassType - true - else - false - end - end - - module Private - INSTANCE = AttachedClassType.new.freeze - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb deleted file mode 100644 index cce89b178a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb +++ /dev/null @@ -1,172 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class Base - def self.method_added(method_name) - super(method_name) - # What is now `subtype_of_single?` used to be named `subtype_of?`. Make sure people don't - # override the wrong thing. - # - # NB: Outside of T::Types, we would enforce this by using `sig` and not declaring the method - # as overridable, but doing so here would result in a dependency cycle. - if method_name == :subtype_of? && self != T::Types::Base - raise "`subtype_of?` should not be overridden. You probably want to override " \ - "`subtype_of_single?` instead." - end - end - - # this will be redefined in certain subclasses - def recursively_valid?(obj) - valid?(obj) - end - - def valid?(obj) - raise NotImplementedError - end - - # @return [T::Boolean] This method must be implemented to return whether the subclass is a subtype - # of `type`. This should only be called by `subtype_of?`, which guarantees that `type` will be - # a "single" type, by which we mean it won't be a Union or an Intersection (c.f. - # `isSubTypeSingle` in sorbet). - private def subtype_of_single?(type) - raise NotImplementedError - end - - # Equality is based on name, so be sure the name reflects all relevant state when implementing. - def name - raise NotImplementedError - end - - # Mirrors ruby_typer::core::Types::isSubType - # See https://git.corp.stripe.com/stripe-internal/ruby-typer/blob/9fc8ed998c04ac0b96592ae6bb3493b8a925c5c1/core/types/subtyping.cc#L912-L950 - # - # This method cannot be overridden (see `method_added` above). - # Subclasses only need to implement `subtype_of_single?`). - def subtype_of?(t2) - t1 = self - - if t2.is_a?(T::Private::Types::TypeAlias) - t2 = t2.aliased_type - end - - if t1.is_a?(T::Private::Types::TypeAlias) - return t1.aliased_type.subtype_of?(t2) - end - - # pairs to cover: 1 (_, _) - # 2 (_, And) - # 3 (_, Or) - # 4 (And, _) - # 5 (And, And) - # 6 (And, Or) - # 7 (Or, _) - # 8 (Or, And) - # 9 (Or, Or) - - # 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)} - 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)} - 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)} - end - 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)} - end - - # 1; Start with some special cases - if t1.is_a?(T::Private::Types::Void) - return t2.is_a?(T::Private::Types::Void) - end - - if t1.is_a?(T::Types::Untyped) || t2.is_a?(T::Types::Untyped) - return true - end - - # Rest of (1) - subtype_of_single?(t2) - end - - def to_s - name - end - - def describe_obj(obj) - # Would be redundant to print class and value in these common cases. - case obj - when nil, true, false - return "type #{obj.class}" - end - - # In rare cases, obj.inspect may fail, or be undefined, so rescue. - begin - # Default inspect behavior of, eg; `#` is ugly; just print the hash instead, which is more concise/readable. - if obj.method(:inspect).owner == Kernel - "type #{obj.class} with hash #{obj.hash}" - elsif T::Configuration.include_value_in_type_errors? - "type #{obj.class} with value #{T::Utils.string_truncate_middle(obj.inspect, 30, 30)}" - else - "type #{obj.class}" - end - rescue StandardError, SystemStackError - "type #{obj.class} with unprintable value" - end - end - - def error_message_for_obj(obj) - if valid?(obj) - nil - else - error_message(obj) - end - end - - def error_message_for_obj_recursive(obj) - if recursively_valid?(obj) - nil - else - error_message(obj) - end - end - - private def error_message(obj) - "Expected type #{self.name}, got #{describe_obj(obj)}" - end - - def validate!(obj) - err = error_message_for_obj(obj) - raise TypeError.new(err) if err - end - - ### Equality methods (necessary for deduping types with `uniq`) - - def hash - name.hash - end - - # Type equivalence, defined by serializing the type to a string (with - # `#name`) and comparing the resulting strings for equality. - def ==(other) - (T::Utils.resolve_alias(other).class == T::Utils.resolve_alias(self).class) && - other.name == self.name - end - - alias_method :eql?, :== - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb deleted file mode 100644 index d56f21d4c7..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Validates that an object belongs to the specified class. - class ClassOf < Base - attr_reader :type - - def initialize(type) - @type = type - end - - # overrides Base - def name - "T.class_of(#{@type})" - end - - # overrides Base - def valid?(obj) - obj.is_a?(Module) && obj <= @type - end - - # overrides Base - def subtype_of_single?(other) - case other - when ClassOf - @type <= other.type - when Simple - @type.is_a?(other.raw_type) - else - false - end - end - - # overrides Base - def describe_obj(obj) - obj.inspect - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb deleted file mode 100644 index 97ecfe0c0c..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # validates that the provided value is within a given set/enum - class Enum < Base - extend T::Sig - - attr_reader :values - - def initialize(values) - @values = values - end - - # overrides Base - def valid?(obj) - @values.member?(obj) - end - - # overrides Base - private def subtype_of_single?(other) - case other - when Enum - (other.values - @values).empty? - else - false - end - end - - # overrides Base - def name - "T.deprecated_enum([#{@values.map(&:inspect).join(', ')}])" - end - - # overrides Base - def describe_obj(obj) - obj.inspect - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb deleted file mode 100644 index 3bed082bcc..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true -# https://jira.corp.stripe.com/browse/RUBYPLAT-1107 -# typed: false - -module T::Types - # Takes a list of types. Validates each item in an array using the type in the same position - # in the list. - class FixedArray < Base - attr_reader :types - - def initialize(types) - @types = types.map {|type| T::Utils.coerce(type)} - end - - # overrides Base - def name - "[#{@types.join(', ')}]" - end - - # overrides Base - def recursively_valid?(obj) - if obj.is_a?(Array) && obj.length == @types.length - i = 0 - while i < @types.length - if !@types[i].recursively_valid?(obj[i]) - return false - end - i += 1 - end - true - else - false - end - end - - # overrides Base - def valid?(obj) - if obj.is_a?(Array) && obj.length == @types.length - i = 0 - while i < @types.length - if !@types[i].valid?(obj[i]) - return false - end - i += 1 - end - true - else - false - end - end - - # overrides Base - private def subtype_of_single?(other) - case other - when FixedArray - # Properly speaking, covariance here is unsound since arrays - # can be mutated, but sorbet implements covariant tuples for - # ease of adoption. - @types.size == other.types.size && @types.zip(other.types).all? do |t1, t2| - t1.subtype_of?(t2) - end - else - false - end - end - - # This gives us better errors, e.g.: - # "Expected [String, Symbol], got [String, String]" - # instead of - # "Expected [String, Symbol], got Array". - # - # overrides Base - def describe_obj(obj) - if obj.is_a?(Array) - if obj.length == @types.length - item_classes = obj.map(&:class).join(', ') - "type [#{item_classes}]" - else - "array of size #{obj.length}" - end - else - super - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb deleted file mode 100644 index d8fddb3703..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Takes a hash of types. Validates each item in a hash using the type in the same position - # in the list. - class FixedHash < Base - attr_reader :types - - def initialize(types) - @types = types.transform_values {|v| T::Utils.coerce(v)} - end - - # overrides Base - def name - serialize_hash(@types) - end - - # 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]} - 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]} - true - end - - # overrides Base - private def subtype_of_single?(other) - case other - when FixedHash - # Using `subtype_of?` here instead of == would be unsound - @types == other.types - else - false - end - end - - # This gives us better errors, e.g.: - # `Expected {a: String}, got {a: TrueClass}` - # instead of - # `Expected {a: String}, got Hash`. - # - # overrides Base - def describe_obj(obj) - if obj.is_a?(Hash) - "type #{serialize_hash(obj.transform_values(&:class))}" - else - super - end - end - - private - - def serialize_hash(hash) - entries = hash.map do |(k, v)| - if Symbol === k && ":#{k}" == k.inspect - "#{k}: #{v}" - else - "#{k.inspect} => #{v}" - end - end - - "{#{entries.join(', ')}}" - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb deleted file mode 100644 index 8e4b42f187..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Takes a list of types. Validates that an object matches all of the types. - class Intersection < Base - attr_reader :types - - def initialize(types) - @types = types.flat_map do |type| - type = T::Utils.resolve_alias(type) - if type.is_a?(Intersection) - # Simplify nested intersections (mostly so `name` returns a nicer value) - type.types - else - T::Utils.coerce(type) - end - end.uniq - end - - # overrides Base - def name - "T.all(#{@types.map(&:name).sort.join(', ')})" - end - - # overrides Base - def recursively_valid?(obj) - @types.all? {|type| type.recursively_valid?(obj)} - end - - # overrides Base - def valid?(obj) - @types.all? {|type| type.valid?(obj)} - end - - # overrides Base - private def subtype_of_single?(other) - raise "This should never be reached if you're going through `subtype_of?` (and you should be)" - end - - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb deleted file mode 100644 index c285797480..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # The bottom type - class NoReturn < Base - - def initialize; end - - # overrides Base - def name - "T.noreturn" - end - - # overrides Base - def valid?(obj) - false - end - - # overrides Base - private def subtype_of_single?(other) - true - end - - module Private - INSTANCE = NoReturn.new.freeze - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb deleted file mode 100644 index aece6a3a2f..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Defines the type of a proc (a ruby callable). At runtime, only - # validates that the value is a `::Proc`. - # - # At present, we only support fixed-arity procs with no optional or - # keyword arguments. - class Proc < Base - attr_reader :arg_types - attr_reader :returns - - def initialize(arg_types, returns) - @arg_types = {} - arg_types.each do |key, raw_type| - @arg_types[key] = T::Utils.coerce(raw_type) - end - @returns = T::Utils.coerce(returns) - end - - # overrides Base - def name - args = [] - @arg_types.each do |k, v| - args << "#{k}: #{v.name}" - end - "T.proc.params(#{args.join(', ')}).returns(#{returns})" - end - - # overrides Base - def valid?(obj) - obj.is_a?(::Proc) - end - - # overrides Base - private def subtype_of_single?(other) - case other - when self.class - if arg_types.size != other.arg_types.size - return false - end - arg_types.values.zip(other.arg_types.values).all? do |a, b| - b.subtype_of?(a) - end && returns.subtype_of?(other.returns) - else - false - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb deleted file mode 100644 index e431a3e0f9..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Modeling self-types properly at runtime would require additional tracking, - # so at runtime we permit all values and rely on the static checker. - class SelfType < Base - - def initialize(); end - - # overrides Base - def name - "T.self_type" - end - - # overrides Base - def valid?(obj) - true - end - - # overrides Base - private def subtype_of_single?(other) - case other - when SelfType - true - else - false - end - end - - module Private - INSTANCE = SelfType.new.freeze - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb deleted file mode 100644 index 2789adbb67..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb +++ /dev/null @@ -1,94 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Validates that an object belongs to the specified class. - class Simple < Base - attr_reader :raw_type - - def initialize(raw_type) - @raw_type = raw_type - end - - # overrides Base - def name - # Memoize to mitigate pathological performance with anonymous modules (https://bugs.ruby-lang.org/issues/11119) - # - # `name` isn't normally a hot path for types, but it is used in initializing a T::Types::Union, - # and so in `T.nilable`, and so in runtime constructions like `x = T.let(nil, T.nilable(Integer))`. - @name ||= @raw_type.name.freeze - end - - # overrides Base - def valid?(obj) - obj.is_a?(@raw_type) - end - - # overrides Base - private def subtype_of_single?(other) - case other - when Simple - @raw_type <= other.raw_type - else - false - end - end - - # overrides Base - private def error_message(obj) - error_message = super(obj) - actual_name = obj.class.name - - return error_message unless name == actual_name - - <<~MSG.strip - #{error_message} - - The expected type and received object type have the same name but refer to different constants. - Expected type is #{name} with object id #{@raw_type.__id__}, but received type is #{actual_name} with object id #{obj.class.__id__}. - - There might be a constant reloading problem in your application. - MSG - end - - def to_nilable - @nilable ||= T::Types::Union.new([self, T::Utils::Nilable::NIL_TYPE]) - end - - module Private - module Pool - @cache = ObjectSpace::WeakMap.new - - def self.type_for_module(mod) - cached = @cache[mod] - return cached if cached - - type = if mod == ::Array - T::Array[T.untyped] - elsif mod == ::Hash - T::Hash[T.untyped, T.untyped] - elsif mod == ::Enumerable - T::Enumerable[T.untyped] - elsif mod == ::Enumerator - T::Enumerator[T.untyped] - elsif mod == ::Range - T::Range[T.untyped] - elsif !Object.autoload?(:Set) && Object.const_defined?(:Set) && mod == ::Set - T::Set[T.untyped] - else - Simple.new(mod) - end - - # Unfortunately, we still need to check if the module is frozen, - # since WeakMap adds a finalizer to the key that is added - # to the map, so that it can clear the map entry when the key is - # garbage collected. - # For a frozen object, though, adding a finalizer is not a valid - # operation, so this still raises if `mod` is frozen. - @cache[mod] = type unless mod.frozen? - type - end - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb deleted file mode 100644 index 121368c7b6..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Validates that an object is equal to another T::Enum singleton value. - class TEnum < Base - attr_reader :val - - def initialize(val) - @val = val - end - - # overrides Base - def name - # Strips the #<...> off, just leaving the ... - # Reasoning: the user will have written something like - # T.any(MyEnum::A, MyEnum::B) - # in the type, so we should print what they wrote in errors, not: - # T.any(#, #) - @val.inspect[2..-2] - end - - # overrides Base - def valid?(obj) - @val == obj - end - - # overrides Base - private def subtype_of_single?(other) - case other - when TEnum - @val == other.val - else - false - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb deleted file mode 100644 index fadd2a7eea..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Types - class TypeMember < TypeVariable - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb deleted file mode 100644 index ea82a07cc3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypeParameter < Base - def initialize(name) - raise ArgumentError.new("not a symbol: #{name}") unless name.is_a?(Symbol) - @name = name - end - - def valid?(obj) - true - end - - def subtype_of_single?(type) - true - end - - def name - "T.type_parameter(:#{@name})" - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb deleted file mode 100644 index 8c83de8949..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Types - class TypeTemplate < TypeVariable - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb deleted file mode 100644 index 187119167d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Since we do type erasure at runtime, this just validates the variance and - # provides some syntax for the static type checker - class TypeVariable < Base - attr_reader :variance - - VALID_VARIANCES = %i[in out invariant].freeze - - def initialize(variance) - case variance - when Hash then raise ArgumentError.new("Pass bounds using a block. Got: #{variance}") - when *VALID_VARIANCES then nil - else - raise TypeError.new("invalid variance #{variance}") - end - @variance = variance - end - - def valid?(obj) - true - end - - def subtype_of_single?(type) - true - end - - def name - Untyped.new.name - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb deleted file mode 100644 index 0b5f3541a9..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedArray < TypedEnumerable - # overrides Base - def name - "T::Array[#{@type.name}]" - end - - def underlying_class - Array - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Array) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Array) - end - - def new(*args) - Array.new(*T.unsafe(args)) - end - - class Untyped < TypedArray - def initialize - super(T.untyped) - end - - def valid?(obj) - obj.is_a?(Array) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb deleted file mode 100644 index 65c2631f0a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb +++ /dev/null @@ -1,176 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Note: All subclasses of Enumerable should add themselves to the - # `case` statement below in `describe_obj` in order to get better - # error messages. - class TypedEnumerable < Base - attr_reader :type - - def initialize(type) - @type = T::Utils.coerce(type) - end - - def underlying_class - Enumerable - end - - # overrides Base - def name - "T::Enumerable[#{@type.name}]" - end - - # overrides Base - def valid?(obj) - obj.is_a?(Enumerable) - end - - # overrides Base - def recursively_valid?(obj) - return false unless obj.is_a?(Enumerable) - case obj - when Array - begin - it = 0 - while it < obj.count - return false unless @type.recursively_valid?(obj[it]) - it += 1 - end - true - end - when Hash - return false unless @type.is_a?(FixedArray) - types = @type.types - return false if types.count != 2 - key_type = types[0] - value_type = types[1] - obj.each_pair do |key, val| - # Some objects (I'm looking at you Rack::Utils::HeaderHash) don't - # iterate over a [key, value] array, so we can't juse use the @type.recursively_valid?(v) - return false if !key_type.recursively_valid?(key) || !value_type.recursively_valid?(val) - end - true - when Enumerator::Lazy - # Enumerators can be unbounded: see `[:foo, :bar].cycle` - true - when Enumerator - # Enumerators can be unbounded: see `[:foo, :bar].cycle` - true - when Range - # A nil beginning or a nil end does not provide any type information. That is, nil in a range represents - # boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range - # of unknown types (T::Range[T.untyped]). - # Similarly, `(nil...1)` is not a `T::Range[T.nilable(Integer)]`, it's a boundless range of Integer. - (obj.begin.nil? || @type.recursively_valid?(obj.begin)) && (obj.end.nil? || @type.recursively_valid?(obj.end)) - when Set - obj.each do |item| - return false unless @type.recursively_valid?(item) - end - - true - else - # We don't check the enumerable since it isn't guaranteed to be - # rewindable (e.g. STDIN) and it may be expensive to enumerate - # (e.g. an enumerator that makes an HTTP request)" - true - end - end - - # overrides Base - private def subtype_of_single?(other) - if other.class <= TypedEnumerable && - underlying_class <= other.underlying_class - # Enumerables are covariant because they are read only - # - # Properly speaking, many Enumerable subtypes (e.g. Set) - # should be invariant because they are mutable and support - # both reading and writing. However, Sorbet treats *all* - # Enumerable subclasses as covariant for ease of adoption. - @type.subtype_of?(other.type) - else - false - end - end - - # overrides Base - def describe_obj(obj) - return super unless obj.is_a?(Enumerable) - type_from_instance(obj).name - end - - private def type_from_instances(objs) - return objs.class unless objs.is_a?(Enumerable) - obtained_types = [] - begin - objs.each do |x| - obtained_types << type_from_instance(x) - end - rescue - return T.untyped # all we can do is go with the types we have so far - end - if obtained_types.count > 1 - # Multiple kinds of bad types showed up, we'll suggest a union - # type you might want. - Union.new(obtained_types) - elsif obtained_types.empty? - T.noreturn - else - # Everything was the same bad type, lets just show that - obtained_types.first - end - end - - private def type_from_instance(obj) - if [true, false].include?(obj) - return T::Boolean - elsif !obj.is_a?(Enumerable) - return obj.class - end - - case obj - when Array - T::Array[type_from_instances(obj)] - when Hash - inferred_key = type_from_instances(obj.keys) - inferred_val = type_from_instances(obj.values) - T::Hash[inferred_key, inferred_val] - when Range - # We can't get any information from `NilClass` in ranges (since nil is used to represent boundlessness). - typeable_objects = [obj.begin, obj.end].compact - if typeable_objects.empty? - T::Range[T.untyped] - else - T::Range[type_from_instances(typeable_objects)] - end - when Enumerator::Lazy - T::Enumerator::Lazy[type_from_instances(obj)] - when Enumerator - T::Enumerator[type_from_instances(obj)] - when Set - T::Set[type_from_instances(obj)] - when IO - # Short circuit for anything IO-like (File, etc.). In these cases, - # enumerating the object is a destructive operation and might hang. - obj.class - else - # This is a specialized enumerable type, just return the class. - if T::Configuration::AT_LEAST_RUBY_2_7 - Object.instance_method(:class).bind_call(obj) - else - Object.instance_method(:class).bind(obj).call - end - end - end - - class Untyped < TypedEnumerable - def initialize - super(T.untyped) - end - - def valid?(obj) - obj.is_a?(Enumerable) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb deleted file mode 100644 index e79341eb94..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedEnumerator < TypedEnumerable - attr_reader :type - - def underlying_class - Enumerator - end - - # overrides Base - def name - "T::Enumerator[#{@type.name}]" - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Enumerator) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Enumerator) - end - - def new(*args, &blk) - T.unsafe(Enumerator).new(*args, &blk) - end - - class Untyped < TypedEnumerator - def initialize - super(T.untyped) - end - - def valid?(obj) - obj.is_a?(Enumerator) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb deleted file mode 100644 index 3569be398a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedEnumeratorLazy < TypedEnumerable - attr_reader :type - - def underlying_class - Enumerator::Lazy - end - - # overrides Base - def name - "T::Enumerator::Lazy[#{@type.name}]" - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Enumerator::Lazy) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Enumerator::Lazy) - end - - def new(*args, &blk) - T.unsafe(Enumerator::Lazy).new(*args, &blk) - end - - class Untyped < TypedEnumeratorLazy - def initialize - super(T.untyped) - end - - def valid?(obj) - obj.is_a?(Enumerator::Lazy) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb deleted file mode 100644 index f48e0c1595..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedHash < TypedEnumerable - # Technically we don't need these, but they are a nice api - attr_reader :keys, :values - - def underlying_class - Hash - end - - def initialize(keys:, values:) - @keys = T::Utils.coerce(keys) - @values = T::Utils.coerce(values) - @type = T::Utils.coerce([keys, values]) - end - - # overrides Base - def name - "T::Hash[#{@keys.name}, #{@values.name}]" - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Hash) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Hash) - end - - def new(*args, &blk) - Hash.new(*T.unsafe(args), &blk) - end - - class Untyped < TypedHash - def initialize - super(keys: T.untyped, values: T.untyped) - end - - def valid?(obj) - obj.is_a?(Hash) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb deleted file mode 100644 index 50e2ef9d53..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedRange < TypedEnumerable - attr_reader :type - - def underlying_class - Hash - end - - # overrides Base - def name - "T::Range[#{@type.name}]" - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Range) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Range) - end - - def new(*args) - T.unsafe(Range).new(*args) - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb deleted file mode 100644 index 8c1b2caee3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedSet < TypedEnumerable - attr_reader :type - - def underlying_class - Hash - end - - # overrides Base - def name - "T::Set[#{@type.name}]" - end - - # overrides Base - def recursively_valid?(obj) - # Re-implements non_forcing_is_a? - return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set - return false unless Object.const_defined?(:Set) # Set is not loaded yet - obj.is_a?(Set) && super - end - - # overrides Base - def valid?(obj) - # Re-implements non_forcing_is_a? - return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set - return false unless Object.const_defined?(:Set) # Set is not loaded yet - obj.is_a?(Set) - end - - def new(*args) - # Fine for this to blow up, because hopefully if they're trying to make a - # Set, they don't mind putting (or already have put) a `require 'set'` in - # their program directly. - Set.new(*T.unsafe(args)) - end - - class Untyped < TypedSet - def initialize - super(T.untyped) - end - - def valid?(obj) - # Re-implements non_forcing_is_a? - return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set - return false unless Object.const_defined?(:Set) # Set is not loaded yet - obj.is_a?(Set) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb deleted file mode 100644 index 3729dc48de..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Takes a list of types. Validates that an object matches at least one of the types. - class Union < Base - attr_reader :types - - def initialize(types) - @types = types.flat_map do |type| - type = T::Utils.coerce(type) - if type.is_a?(Union) - # Simplify nested unions (mostly so `name` returns a nicer value) - type.types - else - type - end - end.uniq - end - - # overrides Base - def name - type_shortcuts(@types) - end - - private def type_shortcuts(types) - if types.size == 1 - return types[0].name - end - 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} - "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} - type_shortcuts([T::Private::Types::StringHolder.new("T::Boolean")] + remaining_types) - else - names = types.map(&:name).compact.sort - "T.any(#{names.join(', ')})" - end - end - - # overrides Base - def recursively_valid?(obj) - @types.any? {|type| type.recursively_valid?(obj)} - end - - # overrides Base - def valid?(obj) - @types.any? {|type| type.valid?(obj)} - end - - # overrides Base - private def subtype_of_single?(other) - raise "This should never be reached if you're going through `subtype_of?` (and you should be)" - end - - module Private - module Pool - EMPTY_ARRAY = [].freeze - private_constant :EMPTY_ARRAY - - # @param type_a [T::Types::Base] - # @param type_b [T::Types::Base] - # @param types [Array] optional array of additional T::Types::Base instances - def self.union_of_types(type_a, type_b, types=EMPTY_ARRAY) - if types.empty? - # We aren't guaranteed to detect a simple `T.nilable()` type here - # in cases where there are duplicate types, nested unions, etc. - # - # That's ok, because this is an optimization which isn't necessary for - # correctness. - if type_b == T::Utils::Nilable::NIL_TYPE && type_a.is_a?(T::Types::Simple) - type_a.to_nilable - elsif type_a == T::Utils::Nilable::NIL_TYPE && type_b.is_a?(T::Types::Simple) - type_b.to_nilable - else - Union.new([type_a, type_b]) - end - else - # This can't be a `T.nilable()` case unless there are duplicates, - # which is possible but unexpected. - Union.new([type_a, type_b] + types) - end - end - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb deleted file mode 100644 index a06a633d42..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # A dynamic type, which permits whatever - class Untyped < Base - - def initialize; end - - # overrides Base - def name - "T.untyped" - end - - # overrides Base - def valid?(obj) - true - end - - # overrides Base - private def subtype_of_single?(other) - true - end - - module Private - INSTANCE = Untyped.new.freeze - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb deleted file mode 100644 index 7897eaa38f..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb +++ /dev/null @@ -1,209 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Utils - # Used to convert from a type specification to a `T::Types::Base`. - def self.coerce(val) - if val.is_a?(T::Private::Types::TypeAlias) - val.aliased_type - elsif val.is_a?(T::Types::Base) - val - elsif val.is_a?(Module) - T::Types::Simple::Private::Pool.type_for_module(val) - elsif val.is_a?(::Array) - T::Types::FixedArray.new(val) - elsif val.is_a?(::Hash) - T::Types::FixedHash.new(val) - elsif val.is_a?(T::Private::Methods::DeclBuilder) - T::Private::Methods.finalize_proc(val.decl) - elsif val.is_a?(::T::Enum) - T::Types::TEnum.new(val) - elsif val.is_a?(::String) - raise "Invalid String literal for type constraint. Must be an #{T::Types::Base}, a " \ - "class/module, or an array. Got a String with value `#{val}`." - else - raise "Invalid value for type constraint. Must be an #{T::Types::Base}, a " \ - "class/module, or an array. Got a `#{val.class}`." - end - end - - # Dynamically confirm that `value` is recursively a valid value of - # type `type`, including recursively through collections. Note that - # in some cases this runtime check can be very expensive, especially - # with large collections of objects. - def self.check_type_recursive!(value, type) - T::Private::Casts.cast_recursive(value, type, cast_method: "T.check_type_recursive!") - end - - # Returns the set of all methods (public, protected, private) defined on a module or its - # ancestors, excluding Object and its ancestors. Overrides of methods from Object (and its - # ancestors) are included. - def self.methods_excluding_object(mod) - # We can't just do mod.instance_methods - Object.instance_methods, because that would leave out - # any methods from Object that are overridden in mod. - mod.ancestors.flat_map do |ancestor| - # equivalent to checking Object.ancestors.include?(ancestor) - next [] if Object <= ancestor - ancestor.instance_methods(false) + ancestor.private_instance_methods(false) - end.uniq - end - - # Returns the signature for the `UnboundMethod`, or nil if it's not sig'd - # - # @example T::Utils.signature_for_method(x.method(:foo)) - def self.signature_for_method(method) - T::Private::Methods.signature_for_method(method) - end - - # Returns the signature for the instance method on the supplied module, or nil if it's not found or not typed. - # - # @example T::Utils.signature_for_instance_method(MyClass, :my_method) - def self.signature_for_instance_method(mod, method_name) - T::Private::Methods.signature_for_method(mod.instance_method(method_name)) - end - - def self.wrap_method_with_call_validation_if_needed(mod, method_sig, original_method) - T::Private::Methods::CallValidation.wrap_method_if_needed(mod, method_sig, original_method) - end - - # Unwraps all the sigs. - def self.run_all_sig_blocks - T::Private::Methods.run_all_sig_blocks - end - - # Return the underlying type for a type alias. Otherwise returns type. - def self.resolve_alias(type) - case type - when T::Private::Types::TypeAlias - type.aliased_type - else - type - end - end - - # Give a type which is a subclass of T::Types::Base, determines if the type is a simple nilable type (union of NilClass and something else). - # If so, returns the T::Types::Base of the something else. Otherwise, returns nil. - def self.unwrap_nilable(type) - case type - when T::Types::Union - non_nil_types = type.types.reject {|t| t == Nilable::NIL_TYPE} - return nil if type.types.length == non_nil_types.length - case non_nil_types.length - when 0 then nil - when 1 then non_nil_types.first - else - T::Types::Union::Private::Pool.union_of_types(non_nil_types[0], non_nil_types[1], non_nil_types[2..-1]) - end - else - nil - end - end - - # Returns the arity of a method, unwrapping the sig if needed - def self.arity(method) - arity = method.arity - return arity if arity != -1 || method.is_a?(Proc) - sig = T::Private::Methods.signature_for_method(method) - sig ? sig.method.arity : arity - end - - # Elide the middle of a string as needed and replace it with an ellipsis. - # Keep the given number of characters at the start and end of the string. - # - # This method operates on string length, not byte length. - # - # If the string is shorter than the requested truncation length, return it - # without adding an ellipsis. This method may return a longer string than - # the original if the characters removed are shorter than the ellipsis. - # - # @param [String] str - # - # @param [Fixnum] start_len The length of string before the ellipsis - # @param [Fixnum] end_len The length of string after the ellipsis - # - # @param [String] ellipsis The string to add in place of the elided text - # - # @return [String] - # - def self.string_truncate_middle(str, start_len, end_len, ellipsis='...') - return unless str - - raise ArgumentError.new('must provide start_len') unless start_len - raise ArgumentError.new('must provide end_len') unless end_len - - raise ArgumentError.new('start_len must be >= 0') if start_len < 0 - raise ArgumentError.new('end_len must be >= 0') if end_len < 0 - - str = str.to_s - return str if str.length <= start_len + end_len - - start_part = str[0...start_len - ellipsis.length] - end_part = end_len == 0 ? '' : str[-end_len..-1] - - "#{start_part}#{ellipsis}#{end_part}" - end - - def self.lift_enum(enum) - unless enum.is_a?(T::Types::Enum) - raise ArgumentError.new("#{enum.inspect} is not a T.deprecated_enum") - end - - classes = enum.values.map(&:class).uniq - if classes.empty? - T.untyped - elsif classes.length > 1 - T::Types::Union.new(classes) - else - T::Types::Simple::Private::Pool.type_for_module(classes.first) - end - end - - module Nilable - # :is_union_type, T::Boolean: whether the type is an T::Types::Union type - # :non_nilable_type, Class: if it is an T.nilable type, the corresponding underlying type; otherwise, nil. - TypeInfo = Struct.new(:is_union_type, :non_nilable_type) - - NIL_TYPE = T::Utils.coerce(NilClass) - - def self.get_type_info(prop_type) - if prop_type.is_a?(T::Types::Union) - non_nilable_type = T::Utils.unwrap_nilable(prop_type) - if non_nilable_type&.is_a?(T::Types::Simple) - non_nilable_type = non_nilable_type.raw_type - end - TypeInfo.new(true, non_nilable_type) - else - TypeInfo.new(false, nil) - end - end - - # Get the underlying type inside prop_type: - # - if the type is A, the function returns A - # - if the type is T.nilable(A), the function returns A - def self.get_underlying_type(prop_type) - type_info = get_type_info(prop_type) - if type_info.is_union_type - type_info.non_nilable_type || prop_type - elsif prop_type.is_a?(T::Types::Simple) - prop_type.raw_type - else - prop_type - end - end - - # The difference between this function and the above function is that the Sorbet type, like T::Types::Simple - # is preserved. - def self.get_underlying_type_object(prop_type) - T::Utils.unwrap_nilable(prop_type) || prop_type - end - - def self.is_union_with_nilclass(prop_type) - case prop_type - when T::Types::Union - prop_type.types.include?(NIL_TYPE) - else - false - end - end - end -end From 4a9942d7fc1fa78e5f68eba544a16ec191320552 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 20:41:22 +0200 Subject: [PATCH 034/111] Removed cached submodule --- Library/Taps/homebrew/homebrew-core | 1 - 1 file changed, 1 deletion(-) delete mode 160000 Library/Taps/homebrew/homebrew-core diff --git a/Library/Taps/homebrew/homebrew-core b/Library/Taps/homebrew/homebrew-core deleted file mode 160000 index 65b3469d30..0000000000 --- a/Library/Taps/homebrew/homebrew-core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 65b3469d300943210a42d69f75eae33faafd204c From 0b5a68ca9b85a39c0534dcb1459a2368afb41afd Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 20:43:07 +0200 Subject: [PATCH 035/111] After `brew style --fix` for livecheck command --- Library/Homebrew/livecheck/livecheck.rb | 150 ++++++++++-------- .../Homebrew/livecheck/livecheck_version.rb | 4 +- 2 files changed, 85 insertions(+), 69 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 131c03d332..dd9b8f846d 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -159,15 +159,15 @@ module Homebrew # `formulae_and_casks_to_check` array and prints the results. sig { params( - formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], - full_name: T::Boolean, - handle_name_conflict: T::Boolean, - check_resources: T::Boolean, - json: T::Boolean, - newer_only: T::Boolean, - debug: T::Boolean, - quiet: T::Boolean, - verbose: T::Boolean, + formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], + full_name: T::Boolean, + handle_name_conflict: T::Boolean, + check_resources: T::Boolean, + json: T::Boolean, + newer_only: T::Boolean, + debug: T::Boolean, + quiet: T::Boolean, + verbose: T::Boolean, ).void } def run_checks( @@ -291,23 +291,25 @@ module Homebrew # Only check current and latest versions if we have resources to check against if has_resources - current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } } + current_resources = formula_or_cask.resources.map do |resource| + { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } + end resource_version_info = resource_version( formula_or_cask, - json: json, + json: json, full_name: use_full_name, - verbose: verbose, - debug: debug + verbose: verbose, + debug: debug, ) - latest_resources = resource_version_info.map { |resource| { name: resource[:resource], version: resource[:version][:latest] } } - - else - # In case we don't have any resources for that Formula/Cask - if debug || verbose - onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" + latest_resources = resource_version_info.map do |resource| + { name: resource[:resource], version: resource[:version][:latest] } end + + elsif debug || verbose + # In case we don't have any resources for that Formula/Cask + onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" end end @@ -368,7 +370,7 @@ module Homebrew if check_resources && has_resources && debug puts <<~EOS - ---------- + ---------- EOS end @@ -377,11 +379,11 @@ module Homebrew if check_resources && has_resources resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each_with_index do |resource, i| + current_resources.each_with_index do |resource, _i| current = resource[:version] current_str = current.to_s latest = if latest_resources_names.include?(resource[:name].to_s) - res = latest_resources.detect { |r| r[:name].to_s == resource[:name].to_s } + res = latest_resources.find { |r| r[:name].to_s == resource[:name].to_s } res[:version] else current @@ -398,11 +400,12 @@ module Homebrew current: current_str, latest: latest_str, newer_than_upstream: is_newer_than_upstream, - outdated: is_outdated, + outdated: is_outdated, } resources_info << info end - print_latest_resource_version(resources_info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + print_latest_resource_version(resources_info, verbose: verbose, + ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) end nil @@ -476,10 +479,10 @@ module Homebrew sig { params( package_or_resource: T.any(Formula, Cask::Cask, Resource), - status_str: String, - messages: T.nilable(T::Array[String]), - full_name: T::Boolean, - verbose: T::Boolean, + status_str: String, + messages: T.nilable(T::Array[String]), + full_name: T::Boolean, + verbose: T::Boolean, ).returns(Hash) } def status_hash(package_or_resource, status_str, messages = nil, full_name: false, verbose: false) @@ -509,7 +512,7 @@ module Homebrew # Formats and prints the livecheck result for a resource (for a given Formula or Cask). sig { params(resources_info: Array(Hash), verbose: T::Boolean, ambiguous_cask: T::Boolean).void } def print_latest_resource_version(resources_info, verbose:, ambiguous_cask: false) - resources_info.each_with_index do |info, i| + resources_info.each_with_index do |info, _i| resource_s = "#{Tty.blue}#{info[:resource]}#{Tty.reset}" resource_s += " (livecheckable)" if info[:livecheckable] && verbose @@ -553,7 +556,7 @@ module Homebrew sig { params( - livecheck_url: T.any(String, Symbol), + livecheck_url: T.any(String, Symbol), package_or_resource: T.any(Formula, Cask::Cask, Resource), ).returns(T.nilable(String)) } @@ -673,14 +676,15 @@ module Homebrew end # Identifies the latest version of the resources in a given Formulae/Casks and returns an Array of Hash containing - # the version information for all the resources. Returns an Array with nil value if a latest version couldn't be found for a given resource. + # the version information for all the resources. Returns an Array with nil value if a latest version + # couldn't be found for a given resource. sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), - json: T::Boolean, - full_name: T::Boolean, - verbose: T::Boolean, - debug: T::Boolean, + formula_or_cask: T.any(Formula, Cask::Cask), + json: T::Boolean, + full_name: T::Boolean, + verbose: T::Boolean, + debug: T::Boolean, ).returns(Array(T.nilable(Hash))) } def resource_version( @@ -691,13 +695,13 @@ module Homebrew debug: false ) resources_version = [] - formula_or_cask.resources.each_with_index do |resource, i| + formula_or_cask.resources.each do |resource| has_livecheckable = resource.livecheckable? if debug puts <<~EOS - ---------- + ---------- EOS odebug "Resource: #{resource_name(resource, full_name: full_name)}" @@ -706,7 +710,7 @@ module Homebrew resource_version_info = { resource: resource_name(resource, full_name: full_name), - version: { + version: { current: resource.version, }, } @@ -774,21 +778,17 @@ module Homebrew next end end - next if strategy.blank? + homebrew_curl = case strategy_name when "PageMatch", "HeaderMatch" use_homebrew_curl?(resource, url) end puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - strategy_data = strategy.find_versions( - url: url, - regex: livecheck_regex, - homebrew_curl: homebrew_curl, - &livecheck_strategy_block + url: url, regex: livecheck_regex, + homebrew_curl: homebrew_curl, &livecheck_strategy_block ) - match_version_map = strategy_data[:matches] regex = strategy_data[:regex] messages = strategy_data[:messages] @@ -836,32 +836,46 @@ module Homebrew end end - resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) + resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| + LivecheckVersion.create(resource, v) + end) - if json && verbose - resource_version_info[:meta] = {} - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" - if has_livecheckable - resource_version_info[:meta][:livecheck] = {} - resource_version_info[:meta][:livecheck][:url] = {} - resource_version_info[:meta][:livecheck][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string - if strategy_data[:url].present? && strategy_data[:url] != url - resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] - end - resource_version_info[:meta][:livecheck][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil - resource_version_info[:meta][:livecheck][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? - resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? - resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + next unless json && verbose + resource_version_info[:meta] = {} + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + if has_livecheckable + resource_version_info[:meta][:livecheck] = {} + resource_version_info[:meta][:livecheck][:url] = {} + if livecheck_url.is_a?(Symbol) && livecheck_url_string + resource_version_info[:meta][:livecheck][:url][:symbol] = + livecheck_url end - resource_version_info[:meta][:url] = {} - resource_version_info[:meta][:url][:original] = original_url - resource_version_info[:meta][:url][:processed] = url if url != original_url + if strategy_data[:url].present? && strategy_data[:url] != url + resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] + end + if strategy_data[:final_url] + resource_version_info[:meta][:livecheck][:url][:final] = + strategy_data[:final_url] + end + if homebrew_curl.present? + resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = + homebrew_curl + end + resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil + if strategies.present? + resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| + livecheck_strategy_names[s] + end + end + resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + end + resource_version_info[:meta][:url] = {} + resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url][:processed] = url if url != original_url end - resources_version << resource_version_info else # If there's no livecheck block in resource resource_version_info[:version][:latest] = resource.version @@ -869,8 +883,8 @@ module Homebrew resource_version_info[:meta] = {} resource_version_info[:meta][:url] = resource.url.to_s end - resources_version << resource_version_info end + resources_version << resource_version_info end resources_version end diff --git a/Library/Homebrew/livecheck/livecheck_version.rb b/Library/Homebrew/livecheck/livecheck_version.rb index f1b722ed49..c0753cc4b2 100644 --- a/Library/Homebrew/livecheck/livecheck_version.rb +++ b/Library/Homebrew/livecheck/livecheck_version.rb @@ -11,7 +11,9 @@ module Homebrew include Comparable - sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), version: Version).returns(LivecheckVersion) } + sig { + params(package_or_resource: T.any(Formula, Cask::Cask, Resource), version: Version).returns(LivecheckVersion) + } def self.create(package_or_resource, version) versions = case package_or_resource when Resource From 825707a219faed0098353ecc3405ee99956f9bad Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 20:54:28 +0200 Subject: [PATCH 036/111] Refactored a bit --- Library/Homebrew/dev-cmd/livecheck.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 966cd75a4f..dc080605a7 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -60,7 +60,7 @@ module Homebrew puts Homebrew::EnvConfig.livecheck_watchlist if Homebrew::EnvConfig.livecheck_watchlist.present? end - package_and_resource_to_check = if args.tap + formulae_and_casks_to_check = if args.tap tap = Tap.fetch(args.tap) formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) } casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) } @@ -96,11 +96,11 @@ module Homebrew raise UsageError, "A watchlist file is required when no arguments are given." end - package_and_resource_to_check = package_and_resource_to_check.sort_by do |package_or_resource| - package_or_resource.respond_to?(:token) ? package_or_resource.token : package_or_resource.name + formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| + formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name end - raise UsageError, "No formulae or casks to check." if package_and_resource_to_check.blank? + raise UsageError, "No formulae or casks to check." if formulae_and_casks_to_check.blank? options = { json: args.json?, @@ -113,6 +113,6 @@ module Homebrew verbose: args.verbose?, }.compact - Livecheck.run_checks(package_and_resource_to_check, **options) + Livecheck.run_checks(formulae_and_casks_to_check, **options) end end From 806f0be69af9d03c97e897c8918e86b45b572abb Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 21:28:28 +0200 Subject: [PATCH 037/111] Refactoring in progress --- Library/Homebrew/livecheck/livecheck.rb | 383 ++++++++++++------------ 1 file changed, 190 insertions(+), 193 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index dd9b8f846d..46053f062b 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -367,13 +367,13 @@ module Homebrew next info end - if check_resources && has_resources && debug - puts <<~EOS + # if check_resources && has_resources && debug + # puts <<~EOS - ---------- + # ---------- - EOS - end + # EOS + # end print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) if check_resources && has_resources @@ -404,8 +404,11 @@ module Homebrew } resources_info << info end - print_latest_resource_version(resources_info, verbose: verbose, - ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + print_latest_resource_version( + resources_info, + verbose: verbose, + ambiguous_cask: ambiguous_casks.include?(formula_or_cask) + ) end nil @@ -675,218 +678,212 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end - # Identifies the latest version of the resources in a given Formulae/Casks and returns an Array of Hash containing - # the version information for all the resources. Returns an Array with nil value if a latest version + # Identifies the latest version of the resource in a given Formulae/Casks and returns a Hash containing + # the version information for a resource. Returns a nil value if a latest version # couldn't be found for a given resource. sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), - json: T::Boolean, - full_name: T::Boolean, - verbose: T::Boolean, - debug: T::Boolean, - ).returns(Array(T.nilable(Hash))) + resource: T.any(Resource), + json: T::Boolean, + full_name: T::Boolean, + verbose: T::Boolean, + debug: T::Boolean, + ).returns(T.nilable(Hash)) } def resource_version( - formula_or_cask, + resource, json: false, full_name: false, verbose: false, debug: false ) - resources_version = [] - formula_or_cask.resources.each do |resource| - has_livecheckable = resource.livecheckable? + has_livecheckable = resource.livecheckable? - if debug - puts <<~EOS + if debug + puts <<~EOS - ---------- + EOS + odebug "Resource: #{resource_name(resource, full_name: full_name)}" + odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + end - EOS - odebug "Resource: #{resource_name(resource, full_name: full_name)}" - odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" - end + resource_version_info = { + resource: resource_name(resource, full_name: full_name), + version: { + current: resource.version, + }, + } - resource_version_info = { - resource: resource_name(resource, full_name: full_name), - version: { - current: resource.version, - }, - } + # Check resources with livecheck block (will be updated in the future) + if has_livecheckable + livecheck = resource.livecheck + livecheck_url = livecheck.url + livecheck_regex = livecheck.regex + livecheck_strategy = livecheck.strategy + livecheck_strategy_block = livecheck.strategy_block - # Check resources with livecheck block (will be updated in the future) - if has_livecheckable - livecheck = resource.livecheck - livecheck_url = livecheck.url - livecheck_regex = livecheck.regex - livecheck_strategy = livecheck.strategy - livecheck_strategy_block = livecheck.strategy_block + livecheck_url_string = livecheck_url_to_string( + livecheck_url, + resource, + ) - livecheck_url_string = livecheck_url_to_string( - livecheck_url, - resource, + urls = [livecheck_url_string] if livecheck_url_string + urls ||= checkable_urls(resource) + + checked_urls = [] + + urls.each_with_index do |original_url, i| + # Only preprocess the URL when it's appropriate + url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + original_url + else + preprocess_url(original_url) + end + next if checked_urls.include?(url) + + strategies = Strategy.from_url( + url, + livecheck_strategy: livecheck_strategy, + url_provided: livecheck_url.present?, + regex_provided: livecheck_regex.present?, + block_provided: livecheck_strategy_block.present?, ) - urls = [livecheck_url_string] if livecheck_url_string - urls ||= checkable_urls(resource) + strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + strategy_name = livecheck_strategy_names[strategy] - checked_urls = [] - - urls.each_with_index do |original_url, i| - # Only preprocess the URL when it's appropriate - url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) - original_url + if debug + puts + if livecheck_url.is_a?(Symbol) + # This assumes the URL symbol will fit within the available space + puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url else - preprocess_url(original_url) + puts "URL: #{original_url}" end - next if checked_urls.include?(url) - - strategies = Strategy.from_url( - url, - livecheck_strategy: livecheck_strategy, - url_provided: livecheck_url.present?, - regex_provided: livecheck_regex.present?, - block_provided: livecheck_strategy_block.present?, - ) - - strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first - strategy_name = livecheck_strategy_names[strategy] - - if debug - puts - if livecheck_url.is_a?(Symbol) - # This assumes the URL symbol will fit within the available space - puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url - else - puts "URL: #{original_url}" - end - puts "URL (processed): #{url}" if url != original_url - if strategies.present? && verbose - puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" - end - puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" - puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + puts "URL (processed): #{url}" if url != original_url + if strategies.present? && verbose + puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" end - - if livecheck_strategy.present? - if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) - odebug "#{strategy_name} strategy requires a URL" - next - elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) - odebug "#{strategy_name} strategy does not apply to this URL" - next - end - end - next if strategy.blank? - - homebrew_curl = case strategy_name - when "PageMatch", "HeaderMatch" - use_homebrew_curl?(resource, url) - end - puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - strategy_data = strategy.find_versions( - url: url, regex: livecheck_regex, - homebrew_curl: homebrew_curl, &livecheck_strategy_block - ) - match_version_map = strategy_data[:matches] - regex = strategy_data[:regex] - messages = strategy_data[:messages] - checked_urls << url - - if messages.is_a?(Array) && match_version_map.blank? - puts messages unless json - next if i + 1 < urls.length - - return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) - end - - if debug - if strategy_data[:url].present? && strategy_data[:url] != url - puts "URL (strategy): #{strategy_data[:url]}" - end - puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? - if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex - puts "Regex (strategy): #{strategy_data[:regex].inspect}" - end - puts "Cached?: Yes" if strategy_data[:cached] == true - end - - match_version_map.delete_if do |_match, version| - next true if version.blank? - next false if has_livecheckable - - UNSTABLE_VERSION_KEYWORDS.any? do |rejection| - version.to_s.include?(rejection) - end - end - - next if match_version_map.blank? - - if debug - puts - puts "Matched Versions:" - - if verbose - match_version_map.each do |match, version| - puts "#{match} => #{version.inspect}" - end - else - puts match_version_map.values.join(", ") - end - end - - resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| - LivecheckVersion.create(resource, v) - end) - - next unless json && verbose - - resource_version_info[:meta] = {} - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" - if has_livecheckable - resource_version_info[:meta][:livecheck] = {} - resource_version_info[:meta][:livecheck][:url] = {} - if livecheck_url.is_a?(Symbol) && livecheck_url_string - resource_version_info[:meta][:livecheck][:url][:symbol] = - livecheck_url - end - if strategy_data[:url].present? && strategy_data[:url] != url - resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] - end - if strategy_data[:final_url] - resource_version_info[:meta][:livecheck][:url][:final] = - strategy_data[:final_url] - end - if homebrew_curl.present? - resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = - homebrew_curl - end - resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil - if strategies.present? - resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| - livecheck_strategy_names[s] - end - end - resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? - resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true - - end - resource_version_info[:meta][:url] = {} - resource_version_info[:meta][:url][:original] = original_url - resource_version_info[:meta][:url][:processed] = url if url != original_url + puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? end - else - # If there's no livecheck block in resource - resource_version_info[:version][:latest] = resource.version - if json && verbose - resource_version_info[:meta] = {} - resource_version_info[:meta][:url] = resource.url.to_s + + if livecheck_strategy.present? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + odebug "#{strategy_name} strategy requires a URL" + next + elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + odebug "#{strategy_name} strategy does not apply to this URL" + next + end end + next if strategy.blank? + + homebrew_curl = case strategy_name + when "PageMatch", "HeaderMatch" + use_homebrew_curl?(resource, url) + end + puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? + strategy_data = strategy.find_versions( + url: url, regex: livecheck_regex, + homebrew_curl: homebrew_curl, &livecheck_strategy_block + ) + match_version_map = strategy_data[:matches] + regex = strategy_data[:regex] + messages = strategy_data[:messages] + checked_urls << url + + if messages.is_a?(Array) && match_version_map.blank? + puts messages unless json + next if i + 1 < urls.length + + return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) + end + + if debug + if strategy_data[:url].present? && strategy_data[:url] != url + puts "URL (strategy): #{strategy_data[:url]}" + end + puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + puts "Regex (strategy): #{strategy_data[:regex].inspect}" + end + puts "Cached?: Yes" if strategy_data[:cached] == true + end + + match_version_map.delete_if do |_match, version| + next true if version.blank? + next false if has_livecheckable + + UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + version.to_s.include?(rejection) + end + end + + next if match_version_map.blank? + + if debug + puts + puts "Matched Versions:" + + if verbose + match_version_map.each do |match, version| + puts "#{match} => #{version.inspect}" + end + else + puts match_version_map.values.join(", ") + end + end + + resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| + LivecheckVersion.create(resource, v) + end) + + next unless json + + resource_version_info[:meta] = {} + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + if has_livecheckable + resource_version_info[:meta][:livecheck] = {} + resource_version_info[:meta][:livecheck][:url] = {} + if livecheck_url.is_a?(Symbol) && livecheck_url_string + resource_version_info[:meta][:livecheck][:url][:symbol] = + livecheck_url + end + if strategy_data[:url].present? && strategy_data[:url] != url + resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] + end + if strategy_data[:final_url] + resource_version_info[:meta][:livecheck][:url][:final] = + strategy_data[:final_url] + end + if homebrew_curl.present? + resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = + homebrew_curl + end + resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil + if strategies.present? + resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| + livecheck_strategy_names[s] + end + end + resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + + end + resource_version_info[:meta][:url] = {} + resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url][:processed] = url if url != original_url + end + else + # If there's no livecheck block in resource + resource_version_info[:version][:latest] = resource.version + if json && verbose + resource_version_info[:meta] = {} + resource_version_info[:meta][:url] = resource.url.to_s end - resources_version << resource_version_info end - resources_version + resource_version_info end # Identifies the latest version of the formula and returns a Hash containing From eb2dcf7ea97b864c88a3f7e11a412b8d9a369a48 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 12:29:20 +0500 Subject: [PATCH 038/111] Update livecheck command: Casks don't have resource blocks Co-authored-by: Nanda H Krishna --- Library/Homebrew/dev-cmd/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index dc080605a7..9fa4c9bcc5 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -36,7 +36,7 @@ module Homebrew switch "--json", description: "Output information in JSON format." switch "-r", "--resources", - description: "Check resources with livecheck blocks for a given formulae/casks." + description: "Also check resources for formulae." switch "-q", "--quiet", description: "Suppress warnings, don't print a progress bar for JSON output." switch "--formula", "--formulae", From 6ec81ac31ce270a75ec81a6240db4721c73d9145 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 09:33:01 +0200 Subject: [PATCH 039/111] No need to show that no resources exists for formulae --- Library/Homebrew/livecheck/livecheck.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 46053f062b..d2976bff3c 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -306,11 +306,6 @@ module Homebrew latest_resources = resource_version_info.map do |resource| { name: resource[:resource], version: resource[:version][:latest] } end - - elsif debug || verbose - # In case we don't have any resources for that Formula/Cask - onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" - end end if latest.blank? From 5beb7c177214e4e5774c4318c5f79a8bde39342a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 09:35:41 +0200 Subject: [PATCH 040/111] Simplified check resources' condition for Formulae --- Library/Homebrew/livecheck/livecheck.rb | 33 +++++++++++-------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index d2976bff3c..4bdceab01b 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -284,28 +284,23 @@ module Homebrew end # Check current and latest resources (if "--resources" flag is given) - if check_resources + # Only check current and latest versions if we have resources to check against + if check_resources && formula_or_cask.resources.present? + current_resources = formula_or_cask.resources.map do |resource| + { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } + end - has_resources = formula_or_cask.resources.any? + resource_version_info = resource_version( + formula_or_cask, + json: json, + full_name: use_full_name, + verbose: verbose, + debug: debug, + ) - # Only check current and latest versions if we have resources to check against - if has_resources + latest_resources = resource_version_info.map do |resource| + { name: resource[:resource], version: resource[:version][:latest] } - current_resources = formula_or_cask.resources.map do |resource| - { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } - end - - resource_version_info = resource_version( - formula_or_cask, - json: json, - full_name: use_full_name, - verbose: verbose, - debug: debug, - ) - - latest_resources = resource_version_info.map do |resource| - { name: resource[:resource], version: resource[:version][:latest] } - end end if latest.blank? From fe94bfb0f1693a40454f23c448f63f8db360cb6d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 12:38:00 +0500 Subject: [PATCH 041/111] Updated livecheck_version Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck_version.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck_version.rb b/Library/Homebrew/livecheck/livecheck_version.rb index c0753cc4b2..ba557cf4ad 100644 --- a/Library/Homebrew/livecheck/livecheck_version.rb +++ b/Library/Homebrew/livecheck/livecheck_version.rb @@ -16,9 +16,7 @@ module Homebrew } def self.create(package_or_resource, version) versions = case package_or_resource - when Resource - [version] - when Formula + when Formula, Resource [version] when Cask::Cask version.to_s.split(/[,:]/).map { |s| Version.new(s) } From c074e8c020b5edc911f8034893130ebdb5c2c2a5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 12:38:40 +0500 Subject: [PATCH 042/111] Aligned output with the existing style seen in #latest_version Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 4bdceab01b..484eefbf58 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -693,8 +693,8 @@ module Homebrew puts <<~EOS EOS - odebug "Resource: #{resource_name(resource, full_name: full_name)}" - odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + puts "Resource: #{resource_name(resource, full_name: full_name)}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end resource_version_info = { From 4088c4683e3a38250e12e226a88ff9fef58dd3ed Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 12:39:23 +0500 Subject: [PATCH 043/111] Indenting resources by two spaces Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 484eefbf58..16b4ca54e3 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -521,7 +521,7 @@ module Homebrew info[:version][:latest] end - puts "-- #{resource_s}: #{current_s} ==> #{latest_s}" + puts " #{resource_s}: #{current_s} ==> #{latest_s}" end end From 40bbbd601eca738725e192dd638cbc1e868b7171 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 09:49:19 +0200 Subject: [PATCH 044/111] Refractored `resource_version` to work for a single resource --- Library/Homebrew/livecheck/livecheck.rb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 16b4ca54e3..50813756ce 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -290,17 +290,20 @@ module Homebrew { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } end - resource_version_info = resource_version( - formula_or_cask, - json: json, - full_name: use_full_name, - verbose: verbose, - debug: debug, - ) + resource_version_info = formula_or_cask.resources.map do |resource| + resource_info = resource_version( + resource, + json: json, + full_name: use_full_name, + verbose: verbose, + debug: debug, + ) + resource_info + end latest_resources = resource_version_info.map do |resource| { name: resource[:resource], version: resource[:version][:latest] } - + end end if latest.blank? From 4f8f852fbc86112ba5a8d7255bcda06e7a20cee5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 10:08:39 +0200 Subject: [PATCH 045/111] Refactored `print_latest_version` for resources as well --- Library/Homebrew/livecheck/livecheck.rb | 27 ++++++++++--------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 50813756ce..31a629dfd9 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -360,19 +360,12 @@ module Homebrew next info end - # if check_resources && has_resources && debug - # puts <<~EOS - - # ---------- - - # EOS - # end print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) - if check_resources && has_resources + if check_resources && formula_or_cask.resources.present? resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each_with_index do |resource, _i| + current_resources.each_with_index do |resource| current = resource[:version] current_str = current.to_s latest = if latest_resources_names.include?(resource[:name].to_s) @@ -528,12 +521,14 @@ module Homebrew end end - # Formats and prints the livecheck result for a formula. - sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void } - def print_latest_version(info, verbose:, ambiguous_cask: false) - formula_or_cask_s = "#{Tty.blue}#{info[:formula] || info[:cask]}#{Tty.reset}" - formula_or_cask_s += " (cask)" if ambiguous_cask - formula_or_cask_s += " (guessed)" if !info[:meta][:livecheckable] && verbose + # Formats and prints the livecheck result for a formula/cask/resource. + sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, check_resource: T::Boolean).void } + def print_latest_version(info, verbose:, ambiguous_cask: false, check_resource: false) + package_or_resource_s = " " if check_resource + package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" + package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource + package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && !check_resource && verbose + package_or_resource_s += " (livecheckable)" if check_resource && info[:livecheckable] && verbose current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" @@ -547,7 +542,7 @@ module Homebrew info[:version][:latest] end - puts "#{formula_or_cask_s}: #{current_s} ==> #{latest_s}" + puts "#{package_or_resource_s}: #{current_s} ==> #{latest_s}" end sig { From 4de65099060a613a37bde2c225d419ef0981cbf6 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 10:09:20 +0200 Subject: [PATCH 046/111] Removed `print_latest_resource_version` --- Library/Homebrew/livecheck/livecheck.rb | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 31a629dfd9..eabd984ab8 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -498,29 +498,6 @@ module Homebrew status_hash end - # Formats and prints the livecheck result for a resource (for a given Formula or Cask). - sig { params(resources_info: Array(Hash), verbose: T::Boolean, ambiguous_cask: T::Boolean).void } - def print_latest_resource_version(resources_info, verbose:, ambiguous_cask: false) - resources_info.each_with_index do |info, _i| - resource_s = "#{Tty.blue}#{info[:resource]}#{Tty.reset}" - resource_s += " (livecheckable)" if info[:livecheckable] && verbose - - current_s = if info[:version][:newer_than_upstream] - "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" - else - info[:version][:current] - end - - latest_s = if info[:version][:outdated] - "#{Tty.green}#{info[:version][:latest]}#{Tty.reset}" - else - info[:version][:latest] - end - - puts " #{resource_s}: #{current_s} ==> #{latest_s}" - end - end - # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, check_resource: T::Boolean).void } def print_latest_version(info, verbose:, ambiguous_cask: false, check_resource: false) From ce202dc61c5924c1b5257c7bf3b6aa577095f61b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 10:17:15 +0200 Subject: [PATCH 047/111] Updated livecheck: Refactored for resources' output --- Library/Homebrew/livecheck/livecheck.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index eabd984ab8..2372ef13e3 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -360,12 +360,12 @@ module Homebrew next info end - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), check_resource: false) if check_resources && formula_or_cask.resources.present? resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each_with_index do |resource| + current_resources.each do |resource| current = resource[:version] current_str = current.to_s latest = if latest_resources_names.include?(resource[:name].to_s) @@ -390,11 +390,14 @@ module Homebrew } resources_info << info end - print_latest_resource_version( - resources_info, - verbose: verbose, - ambiguous_cask: ambiguous_casks.include?(formula_or_cask) - ) + resources_info.each do |info| + print_latest_version( + info, + verbose: verbose, + ambiguous_cask: ambiguous_casks.include?(formula_or_cask), + check_resource: true, + ) + end end nil @@ -535,10 +538,8 @@ module Homebrew when :url package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable - # Resource's "url" is considered "stable" by default. And some resources may contain in "head" block as well + # Since resource's "url" is considered "stable" by default. And some resources may contain in "head" block as well package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) - # Not sure how to handle this ? - # Do I have to add :stable / :head in Resources' as well (like it's being implemented in Formula ?) package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage package_or_resource.homepage From b651fe475cf92475be66f5fe5129297dbbc084a9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 10:24:55 +0200 Subject: [PATCH 048/111] Added `newer_than_upstream` and `outdated` in resource info --- Library/Homebrew/livecheck/livecheck.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 2372ef13e3..94a6b3ed1f 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -849,6 +849,8 @@ module Homebrew resource_version_info[:meta][:url] = resource.url.to_s end end + resource_version_info[:version][:newer_than_upstream] = resource_version_info[:version][:current] > resource_version_info[:version][:latest] + resource_version_info[:version][:outdated] = resource_version_info[:version][:current] < resource_version_info[:version][:latest] resource_version_info end From 6daa22bc8ee1d6353bb80a54042dcb5fb4b3a1b2 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 1 Aug 2022 23:34:53 +0200 Subject: [PATCH 049/111] Fixed issue with `print_latest_version` --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 94a6b3ed1f..bf66457896 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -504,7 +504,7 @@ module Homebrew # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, check_resource: T::Boolean).void } def print_latest_version(info, verbose:, ambiguous_cask: false, check_resource: false) - package_or_resource_s = " " if check_resource + package_or_resource_s = check_resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && !check_resource && verbose From e718318eaf094fcd3c80b1b2863dc9d11b9d5950 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 1 Aug 2022 23:50:18 +0200 Subject: [PATCH 050/111] Fixed issue with info[:meta] for resources --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bf66457896..26e5b75844 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -381,7 +381,7 @@ module Homebrew info = {} info[:resource] = resource[:name] - info[:livecheckable] = resource[:livecheckable] + info[:meta] = { livecheckable: resource[:livecheckable], } info[:version] = { current: current_str, latest: latest_str, @@ -508,7 +508,7 @@ module Homebrew package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && !check_resource && verbose - package_or_resource_s += " (livecheckable)" if check_resource && info[:livecheckable] && verbose + package_or_resource_s += " (livecheckable)" if check_resource && info[:meta][:livecheckable] && verbose current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" From 9c4b9b7e147fdee27d3bdb1d28be79e87084e8b4 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 00:27:53 +0200 Subject: [PATCH 051/111] Refactored a bit + `brew style --fix` --- Library/Homebrew/livecheck/livecheck.rb | 48 +++++++++++-------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 26e5b75844..686c0be5ff 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -293,10 +293,10 @@ module Homebrew resource_version_info = formula_or_cask.resources.map do |resource| resource_info = resource_version( resource, - json: json, + json: json, full_name: use_full_name, - verbose: verbose, - debug: debug, + verbose: verbose, + debug: debug, ) resource_info end @@ -360,7 +360,8 @@ module Homebrew next info end - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), check_resource: false) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), +check_resource: false) if check_resources && formula_or_cask.resources.present? resources_info = [] @@ -381,7 +382,7 @@ module Homebrew info = {} info[:resource] = resource[:name] - info[:meta] = { livecheckable: resource[:livecheckable], } + info[:meta] = { livecheckable: resource[:livecheckable] } info[:version] = { current: current_str, latest: latest_str, @@ -390,10 +391,10 @@ module Homebrew } resources_info << info end - resources_info.each do |info| + resources_info.each do |r_info| print_latest_version( - info, - verbose: verbose, + r_info, + verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), check_resource: true, ) @@ -538,7 +539,8 @@ module Homebrew when :url package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable - # Since resource's "url" is considered "stable" by default. And some resources may contain in "head" block as well + # Since resource's "url" is considered "stable" by default. + # And some resources may contain in "head" block as well package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage @@ -785,7 +787,6 @@ module Homebrew version.to_s.include?(rejection) end end - next if match_version_map.blank? if debug @@ -804,14 +805,11 @@ module Homebrew resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| LivecheckVersion.create(resource, v) end) - next unless json - resource_version_info[:meta] = {} - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + resource_version_info[:meta] = { livecheckable: has_livecheckable ? "Yes" : "No" } if has_livecheckable - resource_version_info[:meta][:livecheck] = {} - resource_version_info[:meta][:livecheck][:url] = {} + resource_version_info[:meta][:livecheck] = { url: {} } if livecheck_url.is_a?(Symbol) && livecheck_url_string resource_version_info[:meta][:livecheck][:url][:symbol] = livecheck_url @@ -823,10 +821,7 @@ module Homebrew resource_version_info[:meta][:livecheck][:url][:final] = strategy_data[:final_url] end - if homebrew_curl.present? - resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = - homebrew_curl - end + resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil if strategies.present? resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| @@ -835,22 +830,19 @@ module Homebrew end resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true - end - resource_version_info[:meta][:url] = {} - resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url] = { original: original_url } resource_version_info[:meta][:url][:processed] = url if url != original_url end else # If there's no livecheck block in resource resource_version_info[:version][:latest] = resource.version - if json && verbose - resource_version_info[:meta] = {} - resource_version_info[:meta][:url] = resource.url.to_s - end + resource_version_info[:meta] = { url: resource.url.to_s } if json && verbose end - resource_version_info[:version][:newer_than_upstream] = resource_version_info[:version][:current] > resource_version_info[:version][:latest] - resource_version_info[:version][:outdated] = resource_version_info[:version][:current] < resource_version_info[:version][:latest] + resource_version_info[:version][:newer_than_upstream] = + resource_version_info[:version][:current] > resource_version_info[:version][:latest] + resource_version_info[:version][:outdated] = + resource_version_info[:version][:current] < resource_version_info[:version][:latest] resource_version_info end From 87b8c7bb6d44830b94f1b2cf0e633e24cb934203 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 03:33:34 +0500 Subject: [PATCH 052/111] Added double blank line before resources to better separate the debug output Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- Library/Homebrew/livecheck/livecheck.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 686c0be5ff..ee92b696d1 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -668,9 +668,7 @@ check_resource: false) has_livecheckable = resource.livecheckable? if debug - puts <<~EOS - - EOS + puts "\n\n" puts "Resource: #{resource_name(resource, full_name: full_name)}" puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end From 609485cdd77c020bca51cefc8ed85704e3e649c1 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 00:35:16 +0200 Subject: [PATCH 053/111] Added a blank line before the output from `print_latest_version` in the debug output --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 686c0be5ff..c31edc5c76 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -359,7 +359,7 @@ module Homebrew info.except!(:meta) unless verbose next info end - + puts if debug print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), check_resource: false) From 26cdf025063e8e9d3fa51faa301d255c07342c2a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 00:52:01 +0200 Subject: [PATCH 054/111] Fix typecheck issues for livecheckable resources --- Library/Homebrew/cli/args.rbi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Library/Homebrew/cli/args.rbi b/Library/Homebrew/cli/args.rbi index 32b1cd8e6e..e59eb5cac8 100644 --- a/Library/Homebrew/cli/args.rbi +++ b/Library/Homebrew/cli/args.rbi @@ -30,6 +30,9 @@ module Homebrew sig { returns(T::Boolean) } def newer_only?; end + sig { returns(T::Boolean) } + def resources?; end + sig { returns(T::Boolean) } def full_name?; end From ac614e29f9b411b8f845f7e630ae4c3064b24a7b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 00:54:18 +0200 Subject: [PATCH 055/111] After brew typecheck --fix --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index db1a341f40..e6f0d01399 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -269,7 +269,7 @@ module Homebrew end current_str = current.to_s - current = LivecheckVersion.create(formula_or_cask, current) + current = T.let(LivecheckVersion.create(formula_or_cask, current), T.untyped) latest = if formula&.head_only? formula.head.downloader.fetch_last_commit @@ -321,7 +321,7 @@ module Homebrew end latest_str = latest.to_s - latest = LivecheckVersion.create(formula_or_cask, latest) + latest = T.let(LivecheckVersion.create(formula_or_cask, latest), T.untyped) is_outdated = if formula&.head_only? # A HEAD-only formula is considered outdated if the latest upstream From fd4a02ff349f7a8988394c2de6862a8decf48c23 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 18:35:52 +0500 Subject: [PATCH 056/111] Refactored `check_resource` to `resource` in `print_latest_version` Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e6f0d01399..aee88d19b8 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -503,8 +503,8 @@ check_resource: false) end # Formats and prints the livecheck result for a formula/cask/resource. - sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, check_resource: T::Boolean).void } - def print_latest_version(info, verbose:, ambiguous_cask: false, check_resource: false) + sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } + def print_latest_version(info, verbose:, ambiguous_cask: false, resource: false) package_or_resource_s = check_resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource From 06d45fea8025510df709507d6919be53cd454c92 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 18:36:55 +0500 Subject: [PATCH 057/111] Minor fix: `ambiguous_cask` should be false for `resources` Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index aee88d19b8..0c94611141 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -395,7 +395,7 @@ check_resource: false) print_latest_version( r_info, verbose: verbose, - ambiguous_cask: ambiguous_casks.include?(formula_or_cask), + ambiguous_cask: false, check_resource: true, ) end From 424c5bfce2f441d42a86a394d754ccb408a854d5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 18:37:36 +0500 Subject: [PATCH 058/111] Minor change: update parameters Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 0c94611141..3029a04f4d 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -396,7 +396,7 @@ check_resource: false) r_info, verbose: verbose, ambiguous_cask: false, - check_resource: true, + resource: true, ) end end From 9b31dc7e873a4ca8dfa788ce17906fe7b6fa9ff1 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 18:41:44 +0500 Subject: [PATCH 059/111] Refactored `print_latest_version` for resource Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 3029a04f4d..9f94042906 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -505,11 +505,10 @@ check_resource: false) # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } def print_latest_version(info, verbose:, ambiguous_cask: false, resource: false) - package_or_resource_s = check_resource ? " " : "" + package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" - package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource - package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && !check_resource && verbose - package_or_resource_s += " (livecheckable)" if check_resource && info[:meta][:livecheckable] && verbose + package_or_resource_s += " (cask)" if ambiguous_cask + package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && verbose current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" From 6f79b5dee292257692148017529f6b25badc47cb Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 15:47:32 +0200 Subject: [PATCH 060/111] Minor change: fix the argument for formulae --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 9f94042906..4be77e196f 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -361,7 +361,7 @@ module Homebrew end puts if debug print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), -check_resource: false) +resource: false) if check_resources && formula_or_cask.resources.present? resources_info = [] @@ -396,7 +396,7 @@ check_resource: false) r_info, verbose: verbose, ambiguous_cask: false, - resource: true, + resource: true, ) end end From e7843775379bf300b81424314903adbc582ef397 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 16:07:48 +0200 Subject: [PATCH 061/111] Code refactoring for `info` Hash for resources --- Library/Homebrew/livecheck/livecheck.rb | 33 +++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 4be77e196f..d3349670e9 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -348,21 +348,6 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - info[:resources] = resource_version_info if check_resources - - next if newer_only && !info[:version][:outdated] - - has_a_newer_upstream_version ||= true - - if json - progress&.increment - info.except!(:meta) unless verbose - next info - end - puts if debug - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), -resource: false) - if check_resources && formula_or_cask.resources.present? resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } @@ -391,6 +376,22 @@ resource: false) } resources_info << info end + info[:resources] = resources_info + end + + next if newer_only && !info[:version][:outdated] + + has_a_newer_upstream_version ||= true + + if json + progress&.increment + info.except!(:meta) unless verbose + next info + end + puts if debug + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) + + if check_resources && formula_or_cask.resources.present? resources_info.each do |r_info| print_latest_version( r_info, @@ -650,7 +651,7 @@ resource: false) # couldn't be found for a given resource. sig { params( - resource: T.any(Resource), + resource: Resource, json: T::Boolean, full_name: T::Boolean, verbose: T::Boolean, From 495f8f2193d8477a03bb54c47ecb8b924365096a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 16:59:53 +0200 Subject: [PATCH 062/111] Return `download_name` when `--full-name` is passed for resources --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index d3349670e9..1d381c2710 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -467,7 +467,7 @@ module Homebrew # provided; returns the name otherwise. sig { params(resource: Resource, full_name: T::Boolean).returns(String) } def resource_name(resource, full_name: false) - full_name ? resource.full_name : resource.name + full_name ? resource.download_name : resource.name end sig { From 71648a5714fd00d312d2d61482a3b1dfd4fca675 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:06:03 +0200 Subject: [PATCH 063/111] Updated `brew livecheck` bash completions for `--resources` flag --- completions/bash/brew | 1 + 1 file changed, 1 insertion(+) diff --git a/completions/bash/brew b/completions/bash/brew index 86abb433c2..ea9d874338 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1330,6 +1330,7 @@ _brew_livecheck() { --cask --debug --formula + --resources --full-name --help --installed From c825ab7dfe6680c7df630b97adf2b918a61eeeb1 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:06:17 +0200 Subject: [PATCH 064/111] Updated `brew livecheck` fish completions for `--resources` flag --- completions/fish/brew.fish | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index d1ba1881af..b80f4b814b 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -948,11 +948,12 @@ __fish_brew_complete_arg 'list; and not __fish_seen_argument -l cask -l casks' - __fish_brew_complete_arg 'list; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_installed)' -__fish_brew_complete_cmd 'livecheck' 'Check for newer versions of formulae and/or casks from upstream' +__fish_brew_complete_cmd 'livecheck' 'Check for newer versions of formulae, resources and/or casks from upstream' __fish_brew_complete_arg 'livecheck' -l all -d 'Check all available formulae/casks' __fish_brew_complete_arg 'livecheck' -l cask -d 'Only check casks' __fish_brew_complete_arg 'livecheck' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'livecheck' -l formula -d 'Only check formulae' +__fish_brew_complete_arg 'livecheck' -l resources -d 'Also check resources for formulae' __fish_brew_complete_arg 'livecheck' -l full-name -d 'Print formulae/casks with fully-qualified names' __fish_brew_complete_arg 'livecheck' -l help -d 'Show this message' __fish_brew_complete_arg 'livecheck' -l installed -d 'Check formulae/casks that are currently installed' From 7855e18042267c3b755e49615a4c1ad25c77e9e9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:06:40 +0200 Subject: [PATCH 065/111] Updated `brew livecheck` zsh completions for `--resources` flag --- completions/zsh/_brew | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 7c33b10012..8290d9433f 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -174,7 +174,7 @@ __brew_internal_commands() { 'link:Symlink all of formula'\''s installed files into Homebrew'\''s prefix' 'linkage:Check the library links from the given formula kegs' 'list:List all installed formulae and casks' - 'livecheck:Check for newer versions of formulae and/or casks from upstream' + 'livecheck:Check for newer versions of formulae, resources and/or casks from upstream' 'log:Show the `git log` for formula or cask, or show the log for the Homebrew repository if no formula or cask is provided' 'migrate:Migrate renamed packages to new names, where formula are old names of packages' 'missing:Check the given formula kegs for missing dependencies' @@ -1167,6 +1167,7 @@ _brew_livecheck() { '--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \ '(--all --installed)--tap[Check formulae/casks within the given tap, specified as user`/`repo]' \ '--verbose[Make some output more verbose]' \ + '--resources[Also check resources for formulae]' \ - formula \ '(--cask)--formula[Only check formulae]' \ '*::formula:__brew_formulae' \ From 81a7d6edd732d903ab653400ee4a51d4d8fb896a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:13:17 +0200 Subject: [PATCH 066/111] Fixed issue with --json flag for resources --- Library/Homebrew/livecheck/livecheck.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 1d381c2710..e988ba6535 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -285,7 +285,7 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against - if check_resources && formula_or_cask.resources.present? + if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? current_resources = formula_or_cask.resources.map do |resource| { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } end @@ -348,7 +348,7 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - if check_resources && formula_or_cask.resources.present? + if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } current_resources.each do |resource| @@ -365,16 +365,16 @@ module Homebrew is_newer_than_upstream = current > latest is_outdated = (current != latest) && !is_newer_than_upstream - info = {} - info[:resource] = resource[:name] - info[:meta] = { livecheckable: resource[:livecheckable] } - info[:version] = { + res_info = {} + res_info[:resource] = resource[:name] + res_info[:meta] = { livecheckable: resource[:livecheckable] } + res_info[:version] = { current: current_str, latest: latest_str, newer_than_upstream: is_newer_than_upstream, outdated: is_outdated, } - resources_info << info + resources_info << res_info end info[:resources] = resources_info end From eb9bc93fae552ae4600c9c0b78ef8bd5d19d95a1 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:19:59 +0200 Subject: [PATCH 067/111] Removed unnecessary `:meta` from info hash --- Library/Homebrew/livecheck/livecheck.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e988ba6535..94a08826fd 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -367,7 +367,6 @@ module Homebrew res_info = {} res_info[:resource] = resource[:name] - res_info[:meta] = { livecheckable: resource[:livecheckable] } res_info[:version] = { current: current_str, latest: latest_str, @@ -509,7 +508,7 @@ module Homebrew package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask - package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && verbose + package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable] current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" From 656b18b13a783274dba4c6578a1bd9babf146d1e Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:24:53 +0200 Subject: [PATCH 068/111] Minor change: updated doc for `resource_version` method --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 94a08826fd..010c0c06d6 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -645,7 +645,7 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end - # Identifies the latest version of the resource in a given Formulae/Casks and returns a Hash containing + # Identifies the latest version of the resource in a given Formulae and returns a Hash containing # the version information for a resource. Returns a nil value if a latest version # couldn't be found for a given resource. sig { From 6055f782184658dda1ac32678319152f81daf77b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 18:14:24 +0200 Subject: [PATCH 069/111] Refactored code for resources in `livecheck` command --- Library/Homebrew/livecheck/livecheck.rb | 332 ++++++++++++------------ 1 file changed, 167 insertions(+), 165 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 010c0c06d6..1cdff96ee1 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -286,9 +286,9 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - current_resources = formula_or_cask.resources.map do |resource| - { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } - end + # current_resources = formula_or_cask.resources.map do |resource| + # { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } + # end resource_version_info = formula_or_cask.resources.map do |resource| resource_info = resource_version( @@ -301,9 +301,11 @@ module Homebrew resource_info end - latest_resources = resource_version_info.map do |resource| - { name: resource[:resource], version: resource[:version][:latest] } - end + # p "resource_version_info: #{resource_version_info}" + + # latest_resources = resource_version_info.map do |resource| + # { name: resource[:resource], version: resource[:version][:latest] } + # end end if latest.blank? @@ -348,34 +350,36 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) + if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - resources_info = [] - latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each do |resource| - current = resource[:version] - current_str = current.to_s - latest = if latest_resources_names.include?(resource[:name].to_s) - res = latest_resources.find { |r| r[:name].to_s == resource[:name].to_s } - res[:version] - else - current - end - latest_str = latest.to_s + info[:resources] = resource_version_info + # resources_info = [] + # latest_resources_names = latest_resources.map { |r| r[:name] } + # current_resources.each do |resource| + # current = resource[:version] + # current_str = current.to_s + # latest = if latest_resources_names.include?(resource[:name].to_s) + # res = latest_resources.find { |r| r[:name].to_s == resource[:name].to_s } + # res[:version] + # else + # current + # end + # latest_str = latest.to_s - is_newer_than_upstream = current > latest - is_outdated = (current != latest) && !is_newer_than_upstream + # is_newer_than_upstream = current > latest + # is_outdated = (current != latest) && !is_newer_than_upstream - res_info = {} - res_info[:resource] = resource[:name] - res_info[:version] = { - current: current_str, - latest: latest_str, - newer_than_upstream: is_newer_than_upstream, - outdated: is_outdated, - } - resources_info << res_info - end - info[:resources] = resources_info + # res_info = {} + # res_info[:resource] = resource[:name] + # res_info[:version] = { + # current: current_str, + # latest: latest_str, + # newer_than_upstream: is_newer_than_upstream, + # outdated: is_outdated, + # } + # resources_info << res_info + # end + # info[:resources] = resources_info end next if newer_only && !info[:version][:outdated] @@ -391,7 +395,7 @@ module Homebrew print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) if check_resources && formula_or_cask.resources.present? - resources_info.each do |r_info| + resource_version_info.each do |r_info| print_latest_version( r_info, verbose: verbose, @@ -672,174 +676,172 @@ module Homebrew puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end - resource_version_info = { - resource: resource_name(resource, full_name: full_name), - version: { - current: resource.version, - }, - } + resource_version_info = {} - # Check resources with livecheck block (will be updated in the future) - if has_livecheckable - livecheck = resource.livecheck - livecheck_url = livecheck.url - livecheck_regex = livecheck.regex - livecheck_strategy = livecheck.strategy - livecheck_strategy_block = livecheck.strategy_block + livecheck = resource.livecheck + livecheck_url = has_livecheckable ? livecheck.url : resource.url + livecheck_regex = livecheck&.regex + livecheck_strategy = livecheck&.strategy + livecheck_strategy_block = livecheck&.strategy_block - livecheck_url_string = livecheck_url_to_string( - livecheck_url, - resource, + livecheck_url_string = livecheck_url_to_string( + livecheck_url, + resource, + ) + + urls = [livecheck_url_string] if livecheck_url_string + urls ||= checkable_urls(resource) + + checked_urls = [] + + urls.each_with_index do |original_url, i| + # Only preprocess the URL when it's appropriate + url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + original_url + else + preprocess_url(original_url) + end + next if checked_urls.include?(url) + + strategies = Strategy.from_url( + url, + livecheck_strategy: livecheck_strategy, + url_provided: livecheck_url.present?, + regex_provided: livecheck_regex.present?, + block_provided: livecheck_strategy_block.present?, ) - urls = [livecheck_url_string] if livecheck_url_string - urls ||= checkable_urls(resource) + strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + strategy_name = livecheck_strategy_names[strategy] - checked_urls = [] - - urls.each_with_index do |original_url, i| - # Only preprocess the URL when it's appropriate - url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) - original_url + if debug + puts + if livecheck_url.is_a?(Symbol) + # This assumes the URL symbol will fit within the available space + puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url else - preprocess_url(original_url) + puts "URL: #{original_url}" end - next if checked_urls.include?(url) + puts "URL (processed): #{url}" if url != original_url + if strategies.present? && verbose + puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" + end + puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + end - strategies = Strategy.from_url( - url, - livecheck_strategy: livecheck_strategy, - url_provided: livecheck_url.present?, - regex_provided: livecheck_regex.present?, - block_provided: livecheck_strategy_block.present?, - ) + if livecheck_strategy.present? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + odebug "#{strategy_name} strategy requires a URL" + next + elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + odebug "#{strategy_name} strategy does not apply to this URL" + next + end + end + next if strategy.blank? - strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first - strategy_name = livecheck_strategy_names[strategy] + homebrew_curl = case strategy_name + when "PageMatch", "HeaderMatch" + use_homebrew_curl?(resource, url) + end + puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? + strategy_data = strategy.find_versions( + url: url, regex: livecheck_regex, + homebrew_curl: homebrew_curl, &livecheck_strategy_block + ) + match_version_map = strategy_data[:matches] + regex = strategy_data[:regex] + messages = strategy_data[:messages] + checked_urls << url - if debug - puts - if livecheck_url.is_a?(Symbol) - # This assumes the URL symbol will fit within the available space - puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url - else - puts "URL: #{original_url}" + if messages.is_a?(Array) && match_version_map.blank? + puts messages unless json + next if i + 1 < urls.length + + return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) + end + + if debug + if strategy_data[:url].present? && strategy_data[:url] != url + puts "URL (strategy): #{strategy_data[:url]}" + end + puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + puts "Regex (strategy): #{strategy_data[:regex].inspect}" + end + puts "Cached?: Yes" if strategy_data[:cached] == true + end + + match_version_map.delete_if do |_match, version| + next true if version.blank? + next false if has_livecheckable + + UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + version.to_s.include?(rejection) + end + end + next if match_version_map.blank? + + if debug + puts + puts "Matched Versions:" + + if verbose + match_version_map.each do |match, version| + puts "#{match} => #{version.inspect}" end - puts "URL (processed): #{url}" if url != original_url - if strategies.present? && verbose - puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" - end - puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" - puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + else + puts match_version_map.values.join(", ") end + end - if livecheck_strategy.present? - if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) - odebug "#{strategy_name} strategy requires a URL" - next - elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) - odebug "#{strategy_name} strategy does not apply to this URL" - next - end - end - next if strategy.blank? + res_current = resource.version + res_latest = Version.new(match_version_map.values.max_by do |v| LivecheckVersion.create(resource, v) end) - homebrew_curl = case strategy_name - when "PageMatch", "HeaderMatch" - use_homebrew_curl?(resource, url) - end - puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - strategy_data = strategy.find_versions( - url: url, regex: livecheck_regex, - homebrew_curl: homebrew_curl, &livecheck_strategy_block - ) - match_version_map = strategy_data[:matches] - regex = strategy_data[:regex] - messages = strategy_data[:messages] - checked_urls << url + is_newer_than_upstream = res_current > res_latest + is_outdated = (res_current != res_latest) && !is_newer_than_upstream - if messages.is_a?(Array) && match_version_map.blank? - puts messages unless json - next if i + 1 < urls.length - - return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) - end - - if debug - if strategy_data[:url].present? && strategy_data[:url] != url - puts "URL (strategy): #{strategy_data[:url]}" - end - puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? - if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex - puts "Regex (strategy): #{strategy_data[:regex].inspect}" - end - puts "Cached?: Yes" if strategy_data[:cached] == true - end - - match_version_map.delete_if do |_match, version| - next true if version.blank? - next false if has_livecheckable - - UNSTABLE_VERSION_KEYWORDS.any? do |rejection| - version.to_s.include?(rejection) - end - end - next if match_version_map.blank? - - if debug - puts - puts "Matched Versions:" - - if verbose - match_version_map.each do |match, version| - puts "#{match} => #{version.inspect}" - end - else - puts match_version_map.values.join(", ") - end - end - - resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| - LivecheckVersion.create(resource, v) - end) - next unless json + resource_version_info = { + resource: resource_name(resource, full_name: full_name), + version: { + current: res_current.to_s, + latest: res_latest.to_s, + newer_than_upstream: is_newer_than_upstream, + outdated: is_outdated, + }, + } + if json && verbose resource_version_info[:meta] = { livecheckable: has_livecheckable ? "Yes" : "No" } if has_livecheckable - resource_version_info[:meta][:livecheck] = { url: {} } + res_livecheck = { url: {} } if livecheck_url.is_a?(Symbol) && livecheck_url_string - resource_version_info[:meta][:livecheck][:url][:symbol] = + res_livecheck[:url][:symbol] = livecheck_url end if strategy_data[:url].present? && strategy_data[:url] != url - resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] + res_livecheck[:url][:strategy] = strategy_data[:url] end if strategy_data[:final_url] - resource_version_info[:meta][:livecheck][:url][:final] = + res_livecheck[:url][:final] = strategy_data[:final_url] end - resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil + res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + res_livecheck[:strategy] = strategy.present? ? strategy_name : nil if strategies.present? - resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| + res_livecheck[:strategies] = strategies.map do |s| livecheck_strategy_names[s] end end - resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? - resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + res_livecheck[:regex] = regex.inspect if regex.present? + res_livecheck[:cached] = true if strategy_data[:cached] == true + resource_version_info[:meta][:livecheck] = res_livecheck end resource_version_info[:meta][:url] = { original: original_url } resource_version_info[:meta][:url][:processed] = url if url != original_url end - else - # If there's no livecheck block in resource - resource_version_info[:version][:latest] = resource.version - resource_version_info[:meta] = { url: resource.url.to_s } if json && verbose end - resource_version_info[:version][:newer_than_upstream] = - resource_version_info[:version][:current] > resource_version_info[:version][:latest] - resource_version_info[:version][:outdated] = - resource_version_info[:version][:current] < resource_version_info[:version][:latest] resource_version_info end From b95a5188bff3601929082fed8d1b76a7e629f0df Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 18:34:03 +0200 Subject: [PATCH 070/111] Refactored code for `brew livecheck --resources --json` --- Library/Homebrew/livecheck/livecheck.rb | 56 ++++--------------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 1cdff96ee1..cecd3f00e9 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -285,11 +285,8 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against - if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - # current_resources = formula_or_cask.resources.map do |resource| - # { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } - # end - + check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? + if check_for_resources resource_version_info = formula_or_cask.resources.map do |resource| resource_info = resource_version( resource, @@ -300,12 +297,6 @@ module Homebrew ) resource_info end - - # p "resource_version_info: #{resource_version_info}" - - # latest_resources = resource_version_info.map do |resource| - # { name: resource[:resource], version: resource[:version][:latest] } - # end end if latest.blank? @@ -350,37 +341,7 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - - if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - info[:resources] = resource_version_info - # resources_info = [] - # latest_resources_names = latest_resources.map { |r| r[:name] } - # current_resources.each do |resource| - # current = resource[:version] - # current_str = current.to_s - # latest = if latest_resources_names.include?(resource[:name].to_s) - # res = latest_resources.find { |r| r[:name].to_s == resource[:name].to_s } - # res[:version] - # else - # current - # end - # latest_str = latest.to_s - - # is_newer_than_upstream = current > latest - # is_outdated = (current != latest) && !is_newer_than_upstream - - # res_info = {} - # res_info[:resource] = resource[:name] - # res_info[:version] = { - # current: current_str, - # latest: latest_str, - # newer_than_upstream: is_newer_than_upstream, - # outdated: is_outdated, - # } - # resources_info << res_info - # end - # info[:resources] = resources_info - end + info[:resources] = resource_version_info if check_for_resources next if newer_only && !info[:version][:outdated] @@ -394,7 +355,7 @@ module Homebrew puts if debug print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) - if check_resources && formula_or_cask.resources.present? + if check_for_resources resource_version_info.each do |r_info| print_latest_version( r_info, @@ -512,7 +473,7 @@ module Homebrew package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask - package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable] + package_or_resource_s += " (guessed)" if verbose && !resource && !info[:meta][:livecheckable] current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" @@ -798,7 +759,6 @@ module Homebrew res_current = resource.version res_latest = Version.new(match_version_map.values.max_by do |v| LivecheckVersion.create(resource, v) end) - is_newer_than_upstream = res_current > res_latest is_outdated = (res_current != res_latest) && !is_newer_than_upstream @@ -817,15 +777,13 @@ module Homebrew if has_livecheckable res_livecheck = { url: {} } if livecheck_url.is_a?(Symbol) && livecheck_url_string - res_livecheck[:url][:symbol] = - livecheck_url + res_livecheck[:url][:symbol] = livecheck_url end if strategy_data[:url].present? && strategy_data[:url] != url res_livecheck[:url][:strategy] = strategy_data[:url] end if strategy_data[:final_url] - res_livecheck[:url][:final] = - strategy_data[:final_url] + res_livecheck[:url][:final] = strategy_data[:final_url] end res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? res_livecheck[:strategy] = strategy.present? ? strategy_name : nil From 3d83e181421d775e8fe1a2f9f554704b715972f3 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 19:03:12 +0200 Subject: [PATCH 071/111] Updated `--json` debug info for livecheckable resources --- Library/Homebrew/livecheck/livecheck.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index cecd3f00e9..5663e58514 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -773,9 +773,11 @@ module Homebrew } if json && verbose - resource_version_info[:meta] = { livecheckable: has_livecheckable ? "Yes" : "No" } + resource_version_info[:meta] = { url: { original: original_url } } + resource_version_info[:meta][:url][:processed] = url if url != original_url + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" if has_livecheckable - res_livecheck = { url: {} } + res_livecheck = { url: { original: livecheck_url } } if livecheck_url.is_a?(Symbol) && livecheck_url_string res_livecheck[:url][:symbol] = livecheck_url end @@ -796,8 +798,6 @@ module Homebrew res_livecheck[:cached] = true if strategy_data[:cached] == true resource_version_info[:meta][:livecheck] = res_livecheck end - resource_version_info[:meta][:url] = { original: original_url } - resource_version_info[:meta][:url][:processed] = url if url != original_url end end resource_version_info From 53b0d60f75a6b478e418d660ef7e3fb1145cb601 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 19:14:13 +0200 Subject: [PATCH 072/111] After running `brew style --fix` --- Library/Homebrew/livecheck/livecheck.rb | 56 ++++++++++++------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 5663e58514..efc59530c6 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -353,7 +353,8 @@ module Homebrew next info end puts if debug - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), +resource: false) if check_for_resources resource_version_info.each do |r_info| @@ -758,47 +759,44 @@ module Homebrew end res_current = resource.version - res_latest = Version.new(match_version_map.values.max_by do |v| LivecheckVersion.create(resource, v) end) + res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) is_newer_than_upstream = res_current > res_latest is_outdated = (res_current != res_latest) && !is_newer_than_upstream resource_version_info = { resource: resource_name(resource, full_name: full_name), version: { - current: res_current.to_s, - latest: res_latest.to_s, + current: res_current.to_s, + latest: res_latest.to_s, newer_than_upstream: is_newer_than_upstream, outdated: is_outdated, }, } - if json && verbose - resource_version_info[:meta] = { url: { original: original_url } } - resource_version_info[:meta][:url][:processed] = url if url != original_url - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" - if has_livecheckable - res_livecheck = { url: { original: livecheck_url } } - if livecheck_url.is_a?(Symbol) && livecheck_url_string - res_livecheck[:url][:symbol] = livecheck_url - end - if strategy_data[:url].present? && strategy_data[:url] != url - res_livecheck[:url][:strategy] = strategy_data[:url] - end - if strategy_data[:final_url] - res_livecheck[:url][:final] = strategy_data[:final_url] - end - res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - res_livecheck[:strategy] = strategy.present? ? strategy_name : nil - if strategies.present? - res_livecheck[:strategies] = strategies.map do |s| - livecheck_strategy_names[s] - end - end - res_livecheck[:regex] = regex.inspect if regex.present? - res_livecheck[:cached] = true if strategy_data[:cached] == true - resource_version_info[:meta][:livecheck] = res_livecheck + next unless json + next unless verbose + + resource_version_info[:meta] = { url: { original: original_url } } + resource_version_info[:meta][:url][:processed] = url if url != original_url + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + next unless has_livecheckable + + res_livecheck = { url: { original: livecheck_url } } + res_livecheck[:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + if strategy_data[:url].present? && strategy_data[:url] != url + res_livecheck[:url][:strategy] = strategy_data[:url] + end + res_livecheck[:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + res_livecheck[:strategy] = strategy.present? ? strategy_name : nil + if strategies.present? + res_livecheck[:strategies] = strategies.map do |s| + livecheck_strategy_names[s] end end + res_livecheck[:regex] = regex.inspect if regex.present? + res_livecheck[:cached] = true if strategy_data[:cached] == true + resource_version_info[:meta][:livecheck] = res_livecheck end resource_version_info end From 0c9ff722ae3466ffb56fcbbcd42b1290740c197e Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 19:36:06 +0200 Subject: [PATCH 073/111] Fixed typecheck errors --- Library/Homebrew/livecheck/livecheck.rb | 27 ++++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index efc59530c6..dd80df3010 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -269,7 +269,6 @@ module Homebrew end current_str = current.to_s - current = T.let(LivecheckVersion.create(formula_or_cask, current), T.untyped) latest = if formula&.head_only? formula.head.downloader.fetch_last_commit @@ -314,7 +313,6 @@ module Homebrew end latest_str = latest.to_s - latest = T.let(LivecheckVersion.create(formula_or_cask, latest), T.untyped) is_outdated = if formula&.head_only? # A HEAD-only formula is considered outdated if the latest upstream @@ -453,9 +451,9 @@ resource: false) if formula status_hash[:formula] = formula_name(formula, full_name: full_name) elsif cask - status_hash[:cask] = cask_name(package_or_resource, full_name: full_name) + status_hash[:cask] = cask_name(cask, full_name: full_name) elsif resource - status_hash[:resource] = resource_name(package_or_resource, full_name: full_name) + status_hash[:resource] = resource_name(resource, full_name: full_name) end status_hash[:status] = status_str status_hash[:messages] = messages if messages.is_a?(Array) @@ -509,7 +507,7 @@ resource: false) package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage - package_or_resource.homepage + package_or_resource.homepage unless package_or_resource.is_a?(Resource) end end @@ -582,29 +580,34 @@ resource: false) url end - # livecheck should fetch a URL using brewed curl if the formula/cask + # livecheck should fetch a URL using brewed curl if the formula/resource/cask # contains a `stable`/`url` or `head` URL `using: :homebrew_curl` that # shares the same root domain. - sig { params(formula_or_cask: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } - def use_homebrew_curl?(formula_or_cask, url) + sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), url: String).returns(T::Boolean) } + def use_homebrew_curl?(package_or_resource, url) url_root_domain = Addressable::URI.parse(url)&.domain return false if url_root_domain.blank? # Collect root domains of URLs with `using: :homebrew_curl` homebrew_curl_root_domains = [] - case formula_or_cask + case package_or_resource when Formula [:stable, :head].each do |spec_name| - next unless (spec = formula_or_cask.send(spec_name)) + next unless (spec = package_or_resource.send(spec_name)) next unless spec.using == :homebrew_curl domain = Addressable::URI.parse(spec.url)&.domain homebrew_curl_root_domains << domain if domain.present? end when Cask::Cask - return false unless formula_or_cask.url.using == :homebrew_curl + return false unless package_or_resource.url.using == :homebrew_curl - domain = Addressable::URI.parse(formula_or_cask.url.to_s)&.domain + domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain + homebrew_curl_root_domains << domain if domain.present? + when Resource + return false unless package_or_resource.url == :homebrew_curl + + domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain homebrew_curl_root_domains << domain if domain.present? end From 9598cc128c270bae68a6b6e6fb2d257ef92d060b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:02:05 +0200 Subject: [PATCH 074/111] Disable block length metric for `resource_version` --- Library/Homebrew/livecheck/livecheck.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index dd80df3010..98c6979a45 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -659,6 +659,7 @@ resource: false) checked_urls = [] + # rubocop:disable Metrics/BlockLength urls.each_with_index do |original_url, i| # Only preprocess the URL when it's appropriate url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) From 6b0574acb186e086ed85d6d84a6c457b615fced0 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:23:07 +0200 Subject: [PATCH 075/111] Updated test for resource in `livecheck_version` (i.e: `ibrew tests --only=livecheck/livecheck_version`) --- .../Homebrew/test/livecheck/livecheck_version_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_version_spec.rb b/Library/Homebrew/test/livecheck/livecheck_version_spec.rb index 95f445cd87..dbdaad6585 100644 --- a/Library/Homebrew/test/livecheck/livecheck_version_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_version_spec.rb @@ -6,6 +6,7 @@ require "livecheck/livecheck_version" describe Homebrew::Livecheck::LivecheckVersion do let(:formula) { instance_double(Formula) } let(:cask) { instance_double(Cask::Cask) } + let(:resource) { instance_double(Resource) } before do # Case statements use #=== for case equality purposes @@ -13,6 +14,8 @@ describe Homebrew::Livecheck::LivecheckVersion do allow(Formula).to receive(:===).with(formula).and_return(true) allow(Cask::Cask).to receive(:===).and_call_original allow(Cask::Cask).to receive(:===).with(cask).and_return(true) + allow(Resource).to receive(:===).and_call_original + allow(Resource).to receive(:===).with(resource).and_return(true) end specify "::create" do @@ -28,5 +31,12 @@ describe Homebrew::Livecheck::LivecheckVersion do .to eq ["1.0", "100", "1426778671"] expect(described_class.create(cask, Version.new("0.17.0,20210111183933,226")).versions) .to eq ["0.17.0", "20210111183933", "226"] + + expect(described_class.create(resource, Version.new("1.1.6")).versions).to eq ["1.1.6"] + expect(described_class.create(resource, Version.new("2.19.0,1.8.0")).versions).to eq ["2.19.0,1.8.0"] + expect(described_class.create(resource, Version.new("1.0,100:1426778671")).versions).to eq ["1.0,100:1426778671"] + expect(described_class.create(resource, Version.new("0.17.0,20210111183933,226")).versions) + .to eq ["0.17.0,20210111183933,226"] + end end From 3476493583bc00cf912db27efd75049010210d8d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:47:17 +0200 Subject: [PATCH 076/111] Updated `livecheck_spec.rb` for resources --- .../Homebrew/test/livecheck/livecheck_spec.rb | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 9b68e3f94b..ba85fc6c96 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -26,6 +26,27 @@ describe Homebrew::Livecheck do end end + let(:f_r) do + formula("test") do + desc "Test formula with a resource" + homepage "https://brew.sh" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + + resource "foo" do + url "https://brew.sh/foo-1.0.tar.gz" + sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + livecheck do + url "https://brew.sh/test/releases" + regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + end + end + end + + let(:r) { f_r.resources.first } + let(:c) do Cask::CaskLoader.load(+<<-RUBY) cask "test" do @@ -72,6 +93,16 @@ describe Homebrew::Livecheck do end end + describe "::resource_name" do + it "returns the name of the resource" do + expect(livecheck.resource_name(r)).to eq("foo") + end + + it "returns the full name of the resource" do + expect(livecheck.resource_name(r, full_name: true)).to eq("test--foo") + end + end + describe "::cask_name" do it "returns the token of the cask" do expect(livecheck.cask_name(c)).to eq("test") @@ -83,7 +114,7 @@ describe Homebrew::Livecheck do end describe "::status_hash" do - it "returns a hash containing the livecheck status" do + it "returns a hash containing the livecheck status for a formula" do expect(livecheck.status_hash(f, "error", ["Unable to get versions"])) .to eq({ formula: "test", @@ -94,6 +125,17 @@ describe Homebrew::Livecheck do }, }) end + it "returns a hash containing the livecheck status for a resource" do + expect(livecheck.status_hash(r, "error", ["Unable to get versions"])) + .to eq({ + resource: "foo", + status: "error", + messages: ["Unable to get versions"], + meta: { + livecheckable: true, + }, + }) + end end describe "::livecheck_url_to_string" do From 5d90e0136afe652ecfe0f73214ee6b276408acf3 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:52:46 +0200 Subject: [PATCH 077/111] Added `livecheck_url_to_string` test for resources --- .../Homebrew/test/livecheck/livecheck_spec.rb | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index ba85fc6c96..217e18899a 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -148,6 +148,26 @@ describe Homebrew::Livecheck do end end + let(:f_r_livecheck_url) do + formula("test_livecheck_url") do + desc "Test Livecheck URL formula" + homepage "https://brew.sh" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + resource "foo" do + url "https://brew.sh/foo-1.0.tar.gz" + sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + livecheck do + url "https://brew.sh/test/releases" + regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + end + end + end + + let(:r_livecheck_url) { f_r_livecheck_url.resources.first } + let(:c_livecheck_url) do Cask::CaskLoader.load(+<<-RUBY) cask "test_livecheck_url" do @@ -161,11 +181,16 @@ describe Homebrew::Livecheck do RUBY end - it "returns a URL string when given a livecheck_url string" do + it "returns a URL string when given a livecheck_url string for formula" do f_livecheck_url.livecheck.url(livecheck_url) expect(livecheck.livecheck_url_to_string(livecheck_url, f_livecheck_url)).to eq(livecheck_url) end + it "returns a URL string when given a livecheck_url string for resource" do + r_livecheck_url.livecheck.url(livecheck_url) + expect(livecheck.livecheck_url_to_string(livecheck_url, r_livecheck_url)).to eq(livecheck_url) + end + it "returns a URL symbol when given a valid livecheck_url symbol" do f_livecheck_url.livecheck.url(:head) expect(livecheck.livecheck_url_to_string(head_url, f_livecheck_url)).to eq(head_url) From eba3d5cf1c7873fabfc3bacdf29994c4e5f8495a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:58:10 +0200 Subject: [PATCH 078/111] Added tests for resource when given a valid livecheck_url symbol --- Library/Homebrew/test/livecheck/livecheck_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 217e18899a..c8d2d16131 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -206,6 +206,15 @@ describe Homebrew::Livecheck do c_livecheck_url.livecheck.url(:url) expect(livecheck.livecheck_url_to_string(cask_url, c_livecheck_url)).to eq(cask_url) + + r_livecheck_url.livecheck.url(:url) + expect(livecheck.livecheck_url_to_string(cask_url, r_livecheck_url)).to eq(cask_url) + + r_livecheck_url.livecheck.url(:head) + expect(livecheck.livecheck_url_to_string(head_url, r_livecheck_url)).to eq(head_url) + + r_livecheck_url.livecheck.url(:stable) + expect(livecheck.livecheck_url_to_string(stable_url, r_livecheck_url)).to eq(stable_url) end it "returns nil when not given a string or valid symbol" do From 7ae71097eeab0501c9c2fea9cd22a5112294c1ff Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 21:10:10 +0200 Subject: [PATCH 079/111] Added tests for resources for `livecheck_url_to_string` --- Library/Homebrew/test/livecheck/livecheck_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index c8d2d16131..e8397d7cd8 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -11,6 +11,7 @@ describe Homebrew::Livecheck do let(:homepage_url) { "https://brew.sh" } let(:livecheck_url) { "https://formulae.brew.sh/api/formula/ruby.json" } let(:stable_url) { "https://brew.sh/test-0.0.1.tgz" } + let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" } let(:f) do formula("test") do @@ -220,8 +221,10 @@ describe Homebrew::Livecheck do it "returns nil when not given a string or valid symbol" do expect(livecheck.livecheck_url_to_string(nil, f_livecheck_url)).to be_nil expect(livecheck.livecheck_url_to_string(nil, c_livecheck_url)).to be_nil + expect(livecheck.livecheck_url_to_string(nil, r_livecheck_url)).to be_nil expect(livecheck.livecheck_url_to_string(:invalid_symbol, f_livecheck_url)).to be_nil expect(livecheck.livecheck_url_to_string(:invalid_symbol, c_livecheck_url)).to be_nil + expect(livecheck.livecheck_url_to_string(:invalid_symbol, r_livecheck_url)).to be_nil end end @@ -229,6 +232,7 @@ describe Homebrew::Livecheck do it "returns the list of URLs to check" do expect(livecheck.checkable_urls(f)).to eq([stable_url, head_url, homepage_url]) expect(livecheck.checkable_urls(c)).to eq([cask_url, homepage_url]) + expect(livecheck.checkable_urls(r)).to eq([resource_url]) expect(livecheck.checkable_urls(f_duplicate_urls)).to eq([stable_url, head_url]) end end From 99a32700d2c6c5986944ec83395e0b1f74381ba8 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 21:30:23 +0200 Subject: [PATCH 080/111] Added resources' tests for `use_homebrew_curl?` method --- .../Homebrew/test/livecheck/livecheck_spec.rb | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index e8397d7cd8..40bd67772a 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -155,6 +155,7 @@ describe Homebrew::Livecheck do homepage "https://brew.sh" url "https://brew.sh/test-0.0.1.tgz" head "https://github.com/Homebrew/brew.git" + resource "foo" do url "https://brew.sh/foo-1.0.tar.gz" sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" @@ -254,6 +255,27 @@ describe Homebrew::Livecheck do end end + let(:f_r_homebrew_curl) do + formula("test_homebrew_curl") do + desc "Test homebrew_curl formula" + homepage "https://brew.sh" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + + resource "foo" do + url "https://brew.sh/foo-1.0.tar.gz", using: :homebrew_curl + sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + livecheck do + url "https://brew.sh/test/releases" + regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + end + end + end + + let(:r_homebrew_curl) { f_r_homebrew_curl.resources.first } + let(:c_homebrew_curl) do Cask::CaskLoader.load(+<<-RUBY) cask "test" do @@ -286,6 +308,13 @@ describe Homebrew::Livecheck do expect(livecheck.use_homebrew_curl?(c_homebrew_curl, example_url)).to be(false) end + it "returns `false` if a `using: homebrew_curl` is present in a resource url" do + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, livecheck_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, homepage_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, stable_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, example_url)).to be(false) + end + it "returns `false` if a `using: homebrew_curl` URL is not present" do expect(livecheck.use_homebrew_curl?(f, livecheck_url)).to be(false) expect(livecheck.use_homebrew_curl?(f, homepage_url)).to be(false) @@ -299,6 +328,7 @@ describe Homebrew::Livecheck do it "returns `false` if URL string does not contain a domain" do expect(livecheck.use_homebrew_curl?(f_homebrew_curl, "test")).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, "test")).to be(false) end end From e15f0b22b9b025f5c6e8fe3cbc5f034d577e5768 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 21:30:56 +0200 Subject: [PATCH 081/111] Added resources' tests for `use_homebrew_curl?` method (`brew tests --only=livecheck/livecheck`) --- .../Homebrew/test/livecheck/livecheck_spec.rb | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index e8397d7cd8..40bd67772a 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -155,6 +155,7 @@ describe Homebrew::Livecheck do homepage "https://brew.sh" url "https://brew.sh/test-0.0.1.tgz" head "https://github.com/Homebrew/brew.git" + resource "foo" do url "https://brew.sh/foo-1.0.tar.gz" sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" @@ -254,6 +255,27 @@ describe Homebrew::Livecheck do end end + let(:f_r_homebrew_curl) do + formula("test_homebrew_curl") do + desc "Test homebrew_curl formula" + homepage "https://brew.sh" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + + resource "foo" do + url "https://brew.sh/foo-1.0.tar.gz", using: :homebrew_curl + sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + livecheck do + url "https://brew.sh/test/releases" + regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + end + end + end + + let(:r_homebrew_curl) { f_r_homebrew_curl.resources.first } + let(:c_homebrew_curl) do Cask::CaskLoader.load(+<<-RUBY) cask "test" do @@ -286,6 +308,13 @@ describe Homebrew::Livecheck do expect(livecheck.use_homebrew_curl?(c_homebrew_curl, example_url)).to be(false) end + it "returns `false` if a `using: homebrew_curl` is present in a resource url" do + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, livecheck_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, homepage_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, stable_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, example_url)).to be(false) + end + it "returns `false` if a `using: homebrew_curl` URL is not present" do expect(livecheck.use_homebrew_curl?(f, livecheck_url)).to be(false) expect(livecheck.use_homebrew_curl?(f, homepage_url)).to be(false) @@ -299,6 +328,7 @@ describe Homebrew::Livecheck do it "returns `false` if URL string does not contain a domain" do expect(livecheck.use_homebrew_curl?(f_homebrew_curl, "test")).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, "test")).to be(false) end end From d0355d76401c60a5b4dc900635868740ff261f9b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 21:49:16 +0200 Subject: [PATCH 082/111] Fixed `brew style` issues with livecheck tests --- .../Homebrew/test/livecheck/livecheck_spec.rb | 56 +++++-------------- .../test/livecheck/livecheck_version_spec.rb | 1 - 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 40bd67772a..e74426253d 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -11,7 +11,6 @@ describe Homebrew::Livecheck do let(:homepage_url) { "https://brew.sh" } let(:livecheck_url) { "https://formulae.brew.sh/api/formula/ruby.json" } let(:stable_url) { "https://brew.sh/test-0.0.1.tgz" } - let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" } let(:f) do formula("test") do @@ -24,15 +23,6 @@ describe Homebrew::Livecheck do url "https://formulae.brew.sh/api/formula/ruby.json" regex(/"stable":"(\d+(?:\.\d+)+)"/i) end - end - end - - let(:f_r) do - formula("test") do - desc "Test formula with a resource" - homepage "https://brew.sh" - url "https://brew.sh/test-0.0.1.tgz" - head "https://github.com/Homebrew/brew.git" resource "foo" do url "https://brew.sh/foo-1.0.tar.gz" @@ -46,7 +36,7 @@ describe Homebrew::Livecheck do end end - let(:r) { f_r.resources.first } + let(:r) { f.resources.first } let(:c) do Cask::CaskLoader.load(+<<-RUBY) @@ -66,15 +56,6 @@ describe Homebrew::Livecheck do RUBY end - let(:f_duplicate_urls) do - formula("test_duplicate_urls") do - desc "Test formula with a duplicate URL" - homepage "https://github.com/Homebrew/brew.git" - url "https://brew.sh/test-0.0.1.tgz" - head "https://github.com/Homebrew/brew.git" - end - end - describe "::resolve_livecheck_reference" do context "when a formula/cask has a livecheck block without formula/cask methods" do it "returns [nil, []]" do @@ -126,10 +107,11 @@ describe Homebrew::Livecheck do }, }) end + it "returns a hash containing the livecheck status for a resource" do expect(livecheck.status_hash(r, "error", ["Unable to get versions"])) .to eq({ - resource: "foo", + resource: "foo", status: "error", messages: ["Unable to get versions"], meta: { @@ -141,15 +123,6 @@ describe Homebrew::Livecheck do describe "::livecheck_url_to_string" do let(:f_livecheck_url) do - formula("test_livecheck_url") do - desc "Test Livecheck URL formula" - homepage "https://brew.sh" - url "https://brew.sh/test-0.0.1.tgz" - head "https://github.com/Homebrew/brew.git" - end - end - - let(:f_r_livecheck_url) do formula("test_livecheck_url") do desc "Test Livecheck URL formula" homepage "https://brew.sh" @@ -168,7 +141,7 @@ describe Homebrew::Livecheck do end end - let(:r_livecheck_url) { f_r_livecheck_url.resources.first } + let(:r_livecheck_url) { f_livecheck_url.resources.first } let(:c_livecheck_url) do Cask::CaskLoader.load(+<<-RUBY) @@ -230,6 +203,16 @@ describe Homebrew::Livecheck do end describe "::checkable_urls" do + let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" } + let(:f_duplicate_urls) do + formula("test_duplicate_urls") do + desc "Test formula with a duplicate URL" + homepage "https://github.com/Homebrew/brew.git" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + end + end + it "returns the list of URLs to check" do expect(livecheck.checkable_urls(f)).to eq([stable_url, head_url, homepage_url]) expect(livecheck.checkable_urls(c)).to eq([cask_url, homepage_url]) @@ -252,15 +235,6 @@ describe Homebrew::Livecheck do url "https://formulae.brew.sh/api/formula/ruby.json" regex(/"stable":"(\d+(?:\.\d+)+)"/i) end - end - end - - let(:f_r_homebrew_curl) do - formula("test_homebrew_curl") do - desc "Test homebrew_curl formula" - homepage "https://brew.sh" - url "https://brew.sh/test-0.0.1.tgz" - head "https://github.com/Homebrew/brew.git" resource "foo" do url "https://brew.sh/foo-1.0.tar.gz", using: :homebrew_curl @@ -274,7 +248,7 @@ describe Homebrew::Livecheck do end end - let(:r_homebrew_curl) { f_r_homebrew_curl.resources.first } + let(:r_homebrew_curl) { f_homebrew_curl.resources.first } let(:c_homebrew_curl) do Cask::CaskLoader.load(+<<-RUBY) diff --git a/Library/Homebrew/test/livecheck/livecheck_version_spec.rb b/Library/Homebrew/test/livecheck/livecheck_version_spec.rb index dbdaad6585..14d070ba23 100644 --- a/Library/Homebrew/test/livecheck/livecheck_version_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_version_spec.rb @@ -37,6 +37,5 @@ describe Homebrew::Livecheck::LivecheckVersion do expect(described_class.create(resource, Version.new("1.0,100:1426778671")).versions).to eq ["1.0,100:1426778671"] expect(described_class.create(resource, Version.new("0.17.0,20210111183933,226")).versions) .to eq ["0.17.0,20210111183933,226"] - end end From 1ca2350e3561670d6fe5fa15da63d9534ed35e9d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 22:24:37 +0200 Subject: [PATCH 083/111] Added an error message if `--resources` flag is given with a Cask --- Library/Homebrew/livecheck/livecheck.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 98c6979a45..0ac07948c7 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -218,6 +218,8 @@ module Homebrew formula = formula_or_cask if formula_or_cask.is_a?(Formula) cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) + onoe "'--resources' flag does not work with a Cask" if check_resources && formula_or_cask.is_a?(Cask::Cask) + use_full_name = full_name || ambiguous_names.include?(formula_or_cask) name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) From be7dde6aace68c63e660bd262c2eebe7c86103c4 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 8 Aug 2022 01:37:45 +0200 Subject: [PATCH 084/111] Minor fixes --- Library/Homebrew/livecheck/livecheck.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 0ac07948c7..eb10dc2637 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -513,7 +513,7 @@ resource: false) end end - # Returns an Array containing the formula/cask URLs that can be used by livecheck. + # Returns an Array containing the formula/resource/cask URLs that can be used by livecheck. sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource)).returns(T::Array[String]) } def checkable_urls(package_or_resource) urls = [] @@ -804,10 +804,11 @@ resource: false) res_livecheck[:cached] = true if strategy_data[:cached] == true resource_version_info[:meta][:livecheck] = res_livecheck end + # rubocop:enable Metrics/BlockLength resource_version_info end - # Identifies the latest version of the formula and returns a Hash containing + # Identifies the latest version of the formula/cask and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. # rubocop:disable Metrics/CyclomaticComplexity sig { From a169d79fee435fd87ccdea750ac4c024b826a677 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 8 Aug 2022 01:43:24 +0200 Subject: [PATCH 085/111] Updated `brew livecheck` doc --- docs/Brew-Livecheck.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index fbbef6c7dc..6a1347ca72 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -1,27 +1,29 @@ # `brew livecheck` -The `brew livecheck` command finds the newest version of a formula or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. +The `brew livecheck` command finds the newest version of a formula, resource or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior When livecheck isn't given instructions for how to check for upstream versions, it does the following by default: -1. For formulae: Collect the `head`, `stable`, and `homepage` URLs, in that order. For casks: Collect the `url` and `homepage` URLs, in that order. -1. Determine if any strategies apply to the first URL. If not, try the next URL. -1. If a strategy can be applied, use it to check for new versions. -1. Return the newest version (or an error if versions could not be found at any available URLs). +1. For __formulae__: Collect the `stable`, `head` and `homepage` URLs, in that order. For __casks__: Collect the `appcast`, `url` and `homepage` URLs, in that order. For __resource__: Collect the `url` (since resource's url is considered `stable` by default) +2. Determine if any strategies apply to the first URL. If not, try the next URL. +3. If a strategy can be applied, use it to check for new versions. +4. Return the newest version (or an error if versions could not be found at any available URLs). It's sometimes necessary to override this default behavior to create a working check. If a source doesn't provide the newest version, we need to check a different one. If livecheck doesn't correctly match version text, we need to provide an appropriate regex or `strategy` block. -This can be accomplished by adding a `livecheck` block to the formula/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). +This can be accomplished by adding a `livecheck` block to the formula/resource/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). ## Creating a check -1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. +1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. `brew livecheck --debug --resources ` will provides livecheck's debug information about the resources as well. -1. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. +> Note: `--resources` flag only works with Formulae. -1. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. +2. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. + +3. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. ### General guidelines From d1584b67b9cc21ff387424f4e21bbf05ef610ed7 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 10 Aug 2022 20:50:14 +0200 Subject: [PATCH 086/111] Removed the error message for Cask in case `--resources` flag is given --- Library/Homebrew/livecheck/livecheck.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index eb10dc2637..c34f307eb2 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -218,8 +218,6 @@ module Homebrew formula = formula_or_cask if formula_or_cask.is_a?(Formula) cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) - onoe "'--resources' flag does not work with a Cask" if check_resources && formula_or_cask.is_a?(Cask::Cask) - use_full_name = full_name || ambiguous_names.include?(formula_or_cask) name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) From f9f3d3d84bf419c0a3bd90526d157d2b328a15ad Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 10 Aug 2022 22:00:08 +0200 Subject: [PATCH 087/111] Minor refractoring --- Library/Homebrew/livecheck/livecheck.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index c34f307eb2..b50da24f14 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -284,8 +284,8 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against - check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - if check_for_resources + check_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? + if check_resources resource_version_info = formula_or_cask.resources.map do |resource| resource_info = resource_version( resource, @@ -339,7 +339,7 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - info[:resources] = resource_version_info if check_for_resources + info[:resources] = resource_version_info if check_resources next if newer_only && !info[:version][:outdated] @@ -354,7 +354,7 @@ module Homebrew print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) - if check_for_resources + if check_resources resource_version_info.each do |r_info| print_latest_version( r_info, From c111a5bc9dd3b9ca94d23b678f0ac9a8be955ace Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 11 Aug 2022 21:00:28 +0200 Subject: [PATCH 088/111] Revert back changes + modified `resource_name` method --- Library/Homebrew/livecheck/livecheck.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index b50da24f14..2e2233e4d1 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -284,8 +284,8 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against - check_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - if check_resources + check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? + if check_for_resources resource_version_info = formula_or_cask.resources.map do |resource| resource_info = resource_version( resource, @@ -339,7 +339,7 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - info[:resources] = resource_version_info if check_resources + info[:resources] = resource_version_info if check_for_resources next if newer_only && !info[:version][:outdated] @@ -354,7 +354,7 @@ module Homebrew print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) - if check_resources + if check_for_resources resource_version_info.each do |r_info| print_latest_version( r_info, @@ -430,7 +430,7 @@ resource: false) # provided; returns the name otherwise. sig { params(resource: Resource, full_name: T::Boolean).returns(String) } def resource_name(resource, full_name: false) - full_name ? resource.download_name : resource.name + resource.name end sig { From 54c9338ed4bb944acb8f76cd5195c246de04b64d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 11 Aug 2022 21:25:24 +0200 Subject: [PATCH 089/111] Removed `use_homebrew_curl?` for resources --- Library/Homebrew/livecheck/livecheck.rb | 15 ++----------- .../Homebrew/test/livecheck/livecheck_spec.rb | 22 +------------------ 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 2e2233e4d1..c3eeae87d6 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -583,7 +583,7 @@ resource: false) # livecheck should fetch a URL using brewed curl if the formula/resource/cask # contains a `stable`/`url` or `head` URL `using: :homebrew_curl` that # shares the same root domain. - sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), url: String).returns(T::Boolean) } + sig { params(package_or_resource: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } def use_homebrew_curl?(package_or_resource, url) url_root_domain = Addressable::URI.parse(url)&.domain return false if url_root_domain.blank? @@ -602,11 +602,6 @@ resource: false) when Cask::Cask return false unless package_or_resource.url.using == :homebrew_curl - domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain - homebrew_curl_root_domains << domain if domain.present? - when Resource - return false unless package_or_resource.url == :homebrew_curl - domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain homebrew_curl_root_domains << domain if domain.present? end @@ -707,14 +702,9 @@ resource: false) end next if strategy.blank? - homebrew_curl = case strategy_name - when "PageMatch", "HeaderMatch" - use_homebrew_curl?(resource, url) - end - puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? strategy_data = strategy.find_versions( url: url, regex: livecheck_regex, - homebrew_curl: homebrew_curl, &livecheck_strategy_block + homebrew_curl: false, &livecheck_strategy_block ) match_version_map = strategy_data[:matches] regex = strategy_data[:regex] @@ -791,7 +781,6 @@ resource: false) res_livecheck[:url][:strategy] = strategy_data[:url] end res_livecheck[:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? res_livecheck[:strategy] = strategy.present? ? strategy_name : nil if strategies.present? res_livecheck[:strategies] = strategies.map do |s| diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index e74426253d..069f03fa0d 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -81,7 +81,7 @@ describe Homebrew::Livecheck do end it "returns the full name of the resource" do - expect(livecheck.resource_name(r, full_name: true)).to eq("test--foo") + expect(livecheck.resource_name(r, full_name: true)).to eq("foo") end end @@ -235,21 +235,9 @@ describe Homebrew::Livecheck do url "https://formulae.brew.sh/api/formula/ruby.json" regex(/"stable":"(\d+(?:\.\d+)+)"/i) end - - resource "foo" do - url "https://brew.sh/foo-1.0.tar.gz", using: :homebrew_curl - sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - - livecheck do - url "https://brew.sh/test/releases" - regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) - end - end end end - let(:r_homebrew_curl) { f_homebrew_curl.resources.first } - let(:c_homebrew_curl) do Cask::CaskLoader.load(+<<-RUBY) cask "test" do @@ -282,13 +270,6 @@ describe Homebrew::Livecheck do expect(livecheck.use_homebrew_curl?(c_homebrew_curl, example_url)).to be(false) end - it "returns `false` if a `using: homebrew_curl` is present in a resource url" do - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, livecheck_url)).to be(false) - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, homepage_url)).to be(false) - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, stable_url)).to be(false) - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, example_url)).to be(false) - end - it "returns `false` if a `using: homebrew_curl` URL is not present" do expect(livecheck.use_homebrew_curl?(f, livecheck_url)).to be(false) expect(livecheck.use_homebrew_curl?(f, homepage_url)).to be(false) @@ -302,7 +283,6 @@ describe Homebrew::Livecheck do it "returns `false` if URL string does not contain a domain" do expect(livecheck.use_homebrew_curl?(f_homebrew_curl, "test")).to be(false) - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, "test")).to be(false) end end From 2ae583c836e410dc59d72b13b87daa0ac5a2bdf4 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 11 Aug 2022 21:50:54 +0200 Subject: [PATCH 090/111] Removed `resource_name` method --- Library/Homebrew/livecheck/livecheck.rb | 17 ++++------------- .../Homebrew/test/livecheck/livecheck_spec.rb | 10 ---------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index c3eeae87d6..bf986c6324 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -398,15 +398,13 @@ resource: false) puts JSON.pretty_generate(formulae_checked.compact) end - sig { params(formula_or_cask: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) } + sig { params(formula_or_cask: T.any(Formula, Cask::Cask), full_name: T::Boolean).returns(String) } def formula_or_cask_name(formula_or_cask, full_name: false) case formula_or_cask when Formula formula_name(formula_or_cask, full_name: full_name) when Cask::Cask cask_name(formula_or_cask, full_name: full_name) - when Resource - resource_name(formula_or_cask, full_name: full_name) else T.absurd(formula_or_cask) end @@ -426,13 +424,6 @@ resource: false) full_name ? formula.full_name : formula.name end - # Returns the fully-qualified name of a resource if the `full_name` argument is - # provided; returns the name otherwise. - sig { params(resource: Resource, full_name: T::Boolean).returns(String) } - def resource_name(resource, full_name: false) - resource.name - end - sig { params( package_or_resource: T.any(Formula, Cask::Cask, Resource), @@ -453,7 +444,7 @@ resource: false) elsif cask status_hash[:cask] = cask_name(cask, full_name: full_name) elsif resource - status_hash[:resource] = resource_name(resource, full_name: full_name) + status_hash[:resource] = resource.name end status_hash[:status] = status_str status_hash[:messages] = messages if messages.is_a?(Array) @@ -632,7 +623,7 @@ resource: false) if debug puts "\n\n" - puts "Resource: #{resource_name(resource, full_name: full_name)}" + puts "Resource: #{resource.name}" puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end @@ -758,7 +749,7 @@ resource: false) is_outdated = (res_current != res_latest) && !is_newer_than_upstream resource_version_info = { - resource: resource_name(resource, full_name: full_name), + resource: resource.name, version: { current: res_current.to_s, latest: res_latest.to_s, diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 069f03fa0d..a9f31774fa 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -75,16 +75,6 @@ describe Homebrew::Livecheck do end end - describe "::resource_name" do - it "returns the name of the resource" do - expect(livecheck.resource_name(r)).to eq("foo") - end - - it "returns the full name of the resource" do - expect(livecheck.resource_name(r, full_name: true)).to eq("foo") - end - end - describe "::cask_name" do it "returns the token of the cask" do expect(livecheck.cask_name(c)).to eq("test") From beb4f02ae3f080e3e0e5904b17d3484fd60e2d80 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 11 Aug 2022 21:59:53 +0200 Subject: [PATCH 091/111] Revert back changes in `doc` and `completions` --- completions/bash/brew | 1 - completions/fish/brew.fish | 3 +-- completions/zsh/_brew | 3 +-- docs/Brew-Livecheck.md | 20 +++++++++----------- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/completions/bash/brew b/completions/bash/brew index b9a439efb2..7ee107cea1 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1349,7 +1349,6 @@ _brew_livecheck() { --cask --debug --formula - --resources --full-name --help --installed diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 762412032e..17e0059810 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -958,12 +958,11 @@ __fish_brew_complete_arg 'list; and not __fish_seen_argument -l cask -l casks' - __fish_brew_complete_arg 'list; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_installed)' -__fish_brew_complete_cmd 'livecheck' 'Check for newer versions of formulae, resources and/or casks from upstream' +__fish_brew_complete_cmd 'livecheck' 'Check for newer versions of formulae and/or casks from upstream' __fish_brew_complete_arg 'livecheck' -l all -d 'Check all available formulae/casks' __fish_brew_complete_arg 'livecheck' -l cask -d 'Only check casks' __fish_brew_complete_arg 'livecheck' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'livecheck' -l formula -d 'Only check formulae' -__fish_brew_complete_arg 'livecheck' -l resources -d 'Also check resources for formulae' __fish_brew_complete_arg 'livecheck' -l full-name -d 'Print formulae/casks with fully-qualified names' __fish_brew_complete_arg 'livecheck' -l help -d 'Show this message' __fish_brew_complete_arg 'livecheck' -l installed -d 'Check formulae/casks that are currently installed' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 208c74ccb7..e8b6c5d327 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -175,7 +175,7 @@ __brew_internal_commands() { 'link:Symlink all of formula'\''s installed files into Homebrew'\''s prefix' 'linkage:Check the library links from the given formula kegs' 'list:List all installed formulae and casks' - 'livecheck:Check for newer versions of formulae, resources and/or casks from upstream' + 'livecheck:Check for newer versions of formulae and/or casks from upstream' 'log:Show the `git log` for formula or cask, or show the log for the Homebrew repository if no formula or cask is provided' 'migrate:Migrate renamed packages to new names, where formula are old names of packages' 'missing:Check the given formula kegs for missing dependencies' @@ -1180,7 +1180,6 @@ _brew_livecheck() { '--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \ '(--all --installed)--tap[Check formulae/casks within the given tap, specified as user`/`repo]' \ '--verbose[Make some output more verbose]' \ - '--resources[Also check resources for formulae]' \ - formula \ '(--cask)--formula[Only check formulae]' \ '*::formula:__brew_formulae' \ diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index 6a1347ca72..fbbef6c7dc 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -1,29 +1,27 @@ # `brew livecheck` -The `brew livecheck` command finds the newest version of a formula, resource or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. +The `brew livecheck` command finds the newest version of a formula or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior When livecheck isn't given instructions for how to check for upstream versions, it does the following by default: -1. For __formulae__: Collect the `stable`, `head` and `homepage` URLs, in that order. For __casks__: Collect the `appcast`, `url` and `homepage` URLs, in that order. For __resource__: Collect the `url` (since resource's url is considered `stable` by default) -2. Determine if any strategies apply to the first URL. If not, try the next URL. -3. If a strategy can be applied, use it to check for new versions. -4. Return the newest version (or an error if versions could not be found at any available URLs). +1. For formulae: Collect the `head`, `stable`, and `homepage` URLs, in that order. For casks: Collect the `url` and `homepage` URLs, in that order. +1. Determine if any strategies apply to the first URL. If not, try the next URL. +1. If a strategy can be applied, use it to check for new versions. +1. Return the newest version (or an error if versions could not be found at any available URLs). It's sometimes necessary to override this default behavior to create a working check. If a source doesn't provide the newest version, we need to check a different one. If livecheck doesn't correctly match version text, we need to provide an appropriate regex or `strategy` block. -This can be accomplished by adding a `livecheck` block to the formula/resource/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). +This can be accomplished by adding a `livecheck` block to the formula/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). ## Creating a check -1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. `brew livecheck --debug --resources ` will provides livecheck's debug information about the resources as well. +1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. -> Note: `--resources` flag only works with Formulae. +1. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. -2. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. - -3. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. +1. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. ### General guidelines From 9377346bdf8f2d13d265b1b5fa39bb77ce998909 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 17 Aug 2022 17:41:34 +0200 Subject: [PATCH 092/111] Minor fixes --- Library/Homebrew/livecheck/livecheck.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bf986c6324..57d3e06d1c 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -269,6 +269,7 @@ module Homebrew end current_str = current.to_s + current = LivecheckVersion.create(formula_or_cask, current) latest = if formula&.head_only? formula.head.downloader.fetch_last_commit @@ -287,14 +288,13 @@ module Homebrew check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? if check_for_resources resource_version_info = formula_or_cask.resources.map do |resource| - resource_info = resource_version( + resource_version( resource, json: json, full_name: use_full_name, verbose: verbose, debug: debug, ) - resource_info end end @@ -313,6 +313,7 @@ module Homebrew end latest_str = latest.to_s + latest = LivecheckVersion.create(formula_or_cask, latest) is_outdated = if formula&.head_only? # A HEAD-only formula is considered outdated if the latest upstream @@ -623,8 +624,8 @@ resource: false) if debug puts "\n\n" - puts "Resource: #{resource.name}" - puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + puts "Resource: #{resource.name}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end resource_version_info = {} From 990f71367b196eb886855be1e083e28ef22ae220 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 23 Aug 2022 16:08:18 +0200 Subject: [PATCH 093/111] Refactoring `resource_version` to always return hash info --- Library/Homebrew/livecheck/livecheck.rb | 35 ++++++++++--------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 57d3e06d1c..79260999d0 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -290,10 +290,9 @@ module Homebrew resource_version_info = formula_or_cask.resources.map do |resource| resource_version( resource, - json: json, - full_name: use_full_name, - verbose: verbose, - debug: debug, + json: json, + verbose: verbose, + debug: debug, ) end end @@ -349,19 +348,18 @@ module Homebrew if json progress&.increment info.except!(:meta) unless verbose + resource_version_info.map! { |r| r.except!(:meta) } if check_for_resources && !verbose next info end puts if debug - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), -resource: false) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) if check_for_resources resource_version_info.each do |r_info| print_latest_version( r_info, - verbose: verbose, - ambiguous_cask: false, - resource: true, + verbose: verbose, + resource: true, ) end end @@ -464,7 +462,7 @@ resource: false) package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask - package_or_resource_s += " (guessed)" if verbose && !resource && !info[:meta][:livecheckable] + package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable] current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" @@ -606,17 +604,15 @@ resource: false) # couldn't be found for a given resource. sig { params( - resource: Resource, - json: T::Boolean, - full_name: T::Boolean, - verbose: T::Boolean, - debug: T::Boolean, + resource: Resource, + json: T::Boolean, + verbose: T::Boolean, + debug: T::Boolean, ).returns(T.nilable(Hash)) } def resource_version( resource, json: false, - full_name: false, verbose: false, debug: false ) @@ -707,7 +703,7 @@ resource: false) puts messages unless json next if i + 1 < urls.length - return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) + return status_hash(resource, "error", messages, verbose: verbose) end if debug @@ -759,12 +755,9 @@ resource: false) }, } - next unless json - next unless verbose - resource_version_info[:meta] = { url: { original: original_url } } resource_version_info[:meta][:url][:processed] = url if url != original_url - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + resource_version_info[:meta][:livecheckable] = has_livecheckable next unless has_livecheckable res_livecheck = { url: { original: livecheck_url } } From 8496ca0416d9283a3a0d9a25583cdbd670b53aab Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 14 Sep 2022 03:42:12 +0200 Subject: [PATCH 094/111] Added `skip_conditions` support for resource --- Library/Homebrew/dev-cmd/bump.rb | 19 ++--- Library/Homebrew/livecheck/skip_conditions.rb | 77 +++++++++++-------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index 009865c85d..0bc0bbc96a 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -72,17 +72,18 @@ module Homebrew ambiguous_casks = [] if !args.formula? && !args.cask? - ambiguous_casks = formulae_and_casks.group_by { |item| Livecheck.formula_or_cask_name(item, full_name: true) } - .values - .select { |items| items.length > 1 } - .flatten - .select { |item| item.is_a?(Cask::Cask) } + ambiguous_casks = formulae_and_casks \ + .group_by { |item| Livecheck.package_or_resource_name(item, full_name: true) } + .values + .select { |items| items.length > 1 } + .flatten + .select { |item| item.is_a?(Cask::Cask) } end ambiguous_names = [] unless args.full_name? ambiguous_names = - (formulae_and_casks - ambiguous_casks).group_by { |item| Livecheck.formula_or_cask_name(item) } + (formulae_and_casks - ambiguous_casks).group_by { |item| Livecheck.package_or_resource_name(item) } .values .select { |items| items.length > 1 } .flatten @@ -92,7 +93,7 @@ module Homebrew puts if i.positive? use_full_name = args.full_name? || ambiguous_names.include?(formula_or_cask) - name = Livecheck.formula_or_cask_name(formula_or_cask, full_name: use_full_name) + name = Livecheck.package_or_resource_name(formula_or_cask, full_name: use_full_name) repository = if formula_or_cask.is_a?(Formula) if formula_or_cask.head_only? ohai name @@ -157,7 +158,7 @@ module Homebrew rescue next end - name = Livecheck.formula_or_cask_name(formula_or_cask) + name = Livecheck.package_or_resource_name(formula_or_cask) ambiguous_cask = begin formula_or_cask.is_a?(Cask::Cask) && !args.cask? && Formula[name] rescue FormulaUnavailableError @@ -178,7 +179,7 @@ module Homebrew end def livecheck_result(formula_or_cask) - name = Livecheck.formula_or_cask_name(formula_or_cask) + name = Livecheck.package_or_resource_name(formula_or_cask) referenced_formula_or_cask, = Livecheck.resolve_livecheck_reference(formula_or_cask, full_name: false, debug: false) diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index f5d2f08358..fe93813378 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -6,7 +6,7 @@ require "livecheck/livecheck" module Homebrew module Livecheck # The `Livecheck::SkipConditions` module primarily contains methods that - # check for various formula/cask conditions where a check should be skipped. + # check for various formula/cask/resource conditions where a check should be skipped. # # @api private module SkipConditions @@ -16,14 +16,14 @@ module Homebrew sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), - livecheckable: T::Boolean, - full_name: T::Boolean, - verbose: T::Boolean, + package_or_resource: T.any(Formula, Cask::Cask, Resource), + livecheckable: T::Boolean, + full_name: T::Boolean, + verbose: T::Boolean, ).returns(Hash) } - def formula_or_cask_skip(formula_or_cask, livecheckable, full_name: false, verbose: false) - formula = formula_or_cask if formula_or_cask.is_a?(Formula) + def package_or_resource_skip(package_or_resource, livecheckable, full_name: false, verbose: false) + formula = package_or_resource if package_or_resource.is_a?(Formula) if (stable_url = formula&.stable&.url) stable_is_gist = stable_url.match?(%r{https?://gist\.github(?:usercontent)?\.com/}i) @@ -33,8 +33,8 @@ module Homebrew stable_from_internet_archive = stable_url.match?(%r{https?://web\.archive\.org/}i) end - skip_message = if formula_or_cask.livecheck.skip_msg.present? - formula_or_cask.livecheck.skip_msg + skip_message = if package_or_resource.livecheck&.skip_msg.present? + package_or_resource.livecheck.skip_msg elsif !livecheckable if stable_from_google_code_archive "Stable URL is from Google Code Archive" @@ -45,10 +45,10 @@ module Homebrew end end - return {} if !formula_or_cask.livecheck.skip? && skip_message.blank? + return {} if !package_or_resource.livecheck&.skip? && skip_message.blank? skip_messages = skip_message ? [skip_message] : nil - Livecheck.status_hash(formula_or_cask, "skipped", skip_messages, full_name: full_name, verbose: verbose) + Livecheck.status_hash(package_or_resource, "skipped", skip_messages, full_name: full_name, verbose: verbose) end sig { @@ -157,7 +157,7 @@ module Homebrew # Skip conditions for formulae. FORMULA_CHECKS = [ - :formula_or_cask_skip, + :package_or_resource_skip, :formula_head_only, :formula_deprecated, :formula_disabled, @@ -166,76 +166,85 @@ module Homebrew # Skip conditions for casks. CASK_CHECKS = [ - :formula_or_cask_skip, + :package_or_resource_skip, :cask_discontinued, :cask_version_latest, :cask_url_unversioned, ].freeze - # If a formula/cask should be skipped, we return a hash from + # Skip conditions for resource + RESOURCE_CHECKS = [ + :package_or_resource_skip, + ].freeze + + # If a formula/cask/resource should be skipped, we return a hash from # `Livecheck#status_hash`, which contains a `status` type and sometimes # error `messages`. sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), - full_name: T::Boolean, - verbose: T::Boolean, + package_or_resource: T.any(Formula, Cask::Cask, Resource), + full_name: T::Boolean, + verbose: T::Boolean, ).returns(Hash) } - def skip_information(formula_or_cask, full_name: false, verbose: false) - livecheckable = formula_or_cask.livecheckable? + def skip_information(package_or_resource, full_name: false, verbose: false) + livecheckable = package_or_resource.livecheckable? - checks = case formula_or_cask + checks = case package_or_resource when Formula FORMULA_CHECKS when Cask::Cask CASK_CHECKS + when Resource + RESOURCE_CHECKS end return {} unless checks checks.each do |method_name| - skip_hash = send(method_name, formula_or_cask, livecheckable, full_name: full_name, verbose: verbose) + skip_hash = send(method_name, package_or_resource, livecheckable, full_name: full_name, verbose: verbose) return skip_hash if skip_hash.present? end {} end - # Skip conditions for formulae/casks referenced in a `livecheck` block + # Skip conditions for formulae/casks/resources referenced in a `livecheck` block # are treated differently than normal. We only respect certain skip # conditions (returning the related hash) and others are treated as # errors. sig { params( - livecheck_formula_or_cask: T.any(Formula, Cask::Cask), - original_formula_or_cask_name: String, - full_name: T::Boolean, - verbose: T::Boolean, + livecheck_package_or_resource: T.any(Formula, Cask::Cask, Resource), + original_package_or_resource_name: String, + full_name: T::Boolean, + verbose: T::Boolean, ).returns(T.nilable(Hash)) } def referenced_skip_information( - livecheck_formula_or_cask, - original_formula_or_cask_name, + livecheck_package_or_resource, + original_package_or_resource_name, full_name: false, verbose: false ) skip_info = SkipConditions.skip_information( - livecheck_formula_or_cask, + livecheck_package_or_resource, full_name: full_name, verbose: verbose, ) return if skip_info.blank? - referenced_name = Livecheck.formula_or_cask_name(livecheck_formula_or_cask, full_name: full_name) - referenced_type = case livecheck_formula_or_cask + referenced_name = Livecheck.package_or_resource_name(livecheck_package_or_resource, full_name: full_name) + referenced_type = case livecheck_package_or_resource when Formula :formula when Cask::Cask :cask + when Resource + :resource end if skip_info[:status] != "error" && - !(skip_info[:status] == "skipped" && livecheck_formula_or_cask.livecheck.skip?) + !(skip_info[:status] == "skipped" && livecheck_package_or_resource.livecheck.skip?) error_msg_end = if skip_info[:status] == "skipped" "automatically skipped" else @@ -245,7 +254,7 @@ module Homebrew raise "Referenced #{referenced_type} (#{referenced_name}) is #{error_msg_end}" end - skip_info[referenced_type] = original_formula_or_cask_name + skip_info[referenced_type] = original_package_or_resource_name skip_info end @@ -258,6 +267,8 @@ module Homebrew skip_hash[:formula] elsif skip_hash[:cask].is_a?(String) skip_hash[:cask] + elsif skip_hash[:resource].is_a?(String) + skip_hash[:resource] end return unless name From 7a627565ac1c3c71f0dd87f7379ef41f01d7f9fe Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 14 Sep 2022 04:54:52 +0200 Subject: [PATCH 095/111] Fixed output issue --- Library/Homebrew/livecheck/livecheck.rb | 118 +++++++++++------- Library/Homebrew/livecheck/skip_conditions.rb | 2 +- 2 files changed, 77 insertions(+), 43 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 79260999d0..fe47f0dd51 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -126,11 +126,11 @@ module Homebrew if debug # Print the chain of references for debugging puts "Reference Chain:" - puts formula_or_cask_name(first_formula_or_cask, full_name: full_name) + puts package_or_resource_name(first_formula_or_cask, full_name: full_name) references << referenced_formula_or_cask references.each do |ref_formula_or_cask| - puts formula_or_cask_name(ref_formula_or_cask, full_name: full_name) + puts package_or_resource_name(ref_formula_or_cask, full_name: full_name) end end @@ -179,17 +179,18 @@ module Homebrew ambiguous_casks = [] if handle_name_conflict - ambiguous_casks = formulae_and_casks_to_check.group_by { |item| formula_or_cask_name(item, full_name: true) } - .values - .select { |items| items.length > 1 } - .flatten - .select { |item| item.is_a?(Cask::Cask) } + ambiguous_casks = formulae_and_casks_to_check \ + .group_by { |item| package_or_resource_name(item, full_name: true) } + .values + .select { |items| items.length > 1 } + .flatten + .select { |item| item.is_a?(Cask::Cask) } end ambiguous_names = [] unless full_name ambiguous_names = - (formulae_and_casks_to_check - ambiguous_casks).group_by { |item| formula_or_cask_name(item) } + (formulae_and_casks_to_check - ambiguous_casks).group_by { |item| package_or_resource_name(item) } .values .select { |items| items.length > 1 } .flatten @@ -219,7 +220,7 @@ module Homebrew cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) use_full_name = full_name || ambiguous_names.include?(formula_or_cask) - name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) + name = package_or_resource_name(formula_or_cask, full_name: use_full_name) referenced_formula_or_cask, livecheck_references = resolve_livecheck_reference(formula_or_cask, full_name: use_full_name, debug: debug) @@ -244,11 +245,31 @@ module Homebrew ) end + # Check current and latest resources (if "--resources" flag is given) + # Only check current and latest versions if we have resources to check against + check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? + if check_for_resources + resource_version_info = formula_or_cask.resources.map do |resource| + res_skip_info ||= SkipConditions.skip_information(resource, verbose: verbose) + if res_skip_info.present? + res_skip_info + else + resource_version( + resource, + json: json, + verbose: verbose, + debug: debug, + ) + end + end.compact + end + skip_info ||= SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose) if skip_info.present? next skip_info if json && !newer_only SkipConditions.print_skip_information(skip_info) if !newer_only && !quiet + print_resources_info(resource_version_info, verbose: verbose) if check_for_resources next end @@ -283,20 +304,6 @@ module Homebrew version_info[:latest] if version_info.present? end - # Check current and latest resources (if "--resources" flag is given) - # Only check current and latest versions if we have resources to check against - check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - if check_for_resources - resource_version_info = formula_or_cask.resources.map do |resource| - resource_version( - resource, - json: json, - verbose: verbose, - debug: debug, - ) - end - end - if latest.blank? no_versions_msg = "Unable to get versions" raise Livecheck::Error, no_versions_msg unless json @@ -353,17 +360,7 @@ module Homebrew end puts if debug print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) - - if check_for_resources - resource_version_info.each do |r_info| - print_latest_version( - r_info, - verbose: verbose, - resource: true, - ) - end - end - + print_resources_info(resource_version_info, verbose: verbose) if check_for_resources nil rescue => e Homebrew.failed = true @@ -373,13 +370,18 @@ module Homebrew progress&.increment status_hash(formula_or_cask, "error", [e.to_s], full_name: use_full_name, verbose: verbose) unless quiet elsif !quiet - name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) + name = package_or_resource_name(formula_or_cask, full_name: use_full_name) name += " (cask)" if ambiguous_casks.include?(formula_or_cask) onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}" $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) nil end + if check_for_resources + next if resource_version_info.blank? + next unless resource_version_info.empty? + print_resources_info(resource_version_info, verbose: verbose) + end end # rubocop:enable Metrics/BlockLength @@ -397,15 +399,17 @@ module Homebrew puts JSON.pretty_generate(formulae_checked.compact) end - sig { params(formula_or_cask: T.any(Formula, Cask::Cask), full_name: T::Boolean).returns(String) } - def formula_or_cask_name(formula_or_cask, full_name: false) - case formula_or_cask + sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) } + def package_or_resource_name(package_or_resource, full_name: false) + case package_or_resource when Formula - formula_name(formula_or_cask, full_name: full_name) + formula_name(package_or_resource, full_name: full_name) when Cask::Cask - cask_name(formula_or_cask, full_name: full_name) + cask_name(package_or_resource, full_name: full_name) + when Resource + package_or_resource.name else - T.absurd(formula_or_cask) + T.absurd(package_or_resource) end end @@ -458,7 +462,7 @@ module Homebrew # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } - def print_latest_version(info, verbose:, ambiguous_cask: false, resource: false) + def print_latest_version(info, verbose:false, ambiguous_cask: false, resource: false) package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask @@ -479,6 +483,22 @@ module Homebrew puts "#{package_or_resource_s}: #{current_s} ==> #{latest_s}" end + # Prints the livecheck result for a resources for a given Formula. + sig { params(info: Hash, verbose: T::Boolean).void } + def print_resources_info(info, verbose:false) + info.each do |r_info| + if r_info.is_a?(Hash) && r_info[:status] && r_info[:messages] + SkipConditions.print_skip_information(r_info) + else + print_latest_version( + r_info, + verbose: verbose, + resource: true, + ) + end + end + end + sig { params( livecheck_url: T.any(String, Symbol), @@ -742,6 +762,11 @@ module Homebrew res_current = resource.version res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) + + if res_latest.to_s.blank? + return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) + end + is_newer_than_upstream = res_current > res_latest is_outdated = (res_current != res_latest) && !is_newer_than_upstream @@ -775,6 +800,14 @@ module Homebrew res_livecheck[:regex] = regex.inspect if regex.present? res_livecheck[:cached] = true if strategy_data[:cached] == true resource_version_info[:meta][:livecheck] = res_livecheck + rescue => e + Homebrew.failed = true + if json + status_hash(resource, "error", [e.to_s], verbose: verbose) + elsif onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}" + $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) + nil + end end # rubocop:enable Metrics/BlockLength resource_version_info @@ -950,6 +983,7 @@ module Homebrew end version_info = { + # latest: {}, latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), } diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index fe93813378..7991f2d07d 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -268,7 +268,7 @@ module Homebrew elsif skip_hash[:cask].is_a?(String) skip_hash[:cask] elsif skip_hash[:resource].is_a?(String) - skip_hash[:resource] + " #{skip_hash[:resource]}" end return unless name From c06b80c2ca5f7d017529431352578c049c81731c Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 14 Sep 2022 04:59:01 +0200 Subject: [PATCH 096/111] After `brew style --fix` --- Library/Homebrew/livecheck/livecheck.rb | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index fe47f0dd51..5192f3394b 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -251,16 +251,12 @@ module Homebrew if check_for_resources resource_version_info = formula_or_cask.resources.map do |resource| res_skip_info ||= SkipConditions.skip_information(resource, verbose: verbose) - if res_skip_info.present? - res_skip_info - else - resource_version( - resource, - json: json, - verbose: verbose, - debug: debug, - ) - end + res_skip_info.presence || resource_version( + resource, + json: json, + verbose: verbose, + debug: debug, + ) end.compact end @@ -380,6 +376,7 @@ module Homebrew if check_for_resources next if resource_version_info.blank? next unless resource_version_info.empty? + print_resources_info(resource_version_info, verbose: verbose) end end @@ -462,7 +459,7 @@ module Homebrew # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } - def print_latest_version(info, verbose:false, ambiguous_cask: false, resource: false) + def print_latest_version(info, verbose: false, ambiguous_cask: false, resource: false) package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask @@ -485,7 +482,7 @@ module Homebrew # Prints the livecheck result for a resources for a given Formula. sig { params(info: Hash, verbose: T::Boolean).void } - def print_resources_info(info, verbose:false) + def print_resources_info(info, verbose: false) info.each do |r_info| if r_info.is_a?(Hash) && r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) @@ -763,9 +760,7 @@ module Homebrew res_current = resource.version res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) - if res_latest.to_s.blank? - return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) - end + return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) if res_latest.to_s.blank? is_newer_than_upstream = res_current > res_latest is_outdated = (res_current != res_latest) && !is_newer_than_upstream From f8ef7bd0e9da68bb74d002c8410aa15211f331f8 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 14 Sep 2022 06:05:43 +0200 Subject: [PATCH 097/111] Minor fixes --- Library/Homebrew/livecheck/livecheck.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 5192f3394b..0195e2f7a7 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -307,7 +307,11 @@ module Homebrew next version_info if version_info.is_a?(Hash) && version_info[:status] && version_info[:messages] - next status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, verbose: verbose) + latest_info = status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, + verbose: verbose) + latest_info[:resources] = resource_version_info if check_for_resources + + next latest_info end if (m = latest.to_s.match(/(.*)-release$/)) && !current.to_s.match(/.*-release$/) @@ -373,12 +377,7 @@ module Homebrew $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) nil end - if check_for_resources - next if resource_version_info.blank? - next unless resource_version_info.empty? - - print_resources_info(resource_version_info, verbose: verbose) - end + print_resources_info(resource_version_info, verbose: verbose) if check_for_resources end # rubocop:enable Metrics/BlockLength From 3d9c6ddb755d881756e2bd55c108ce13e92839f5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 18 Sep 2022 17:09:21 +0200 Subject: [PATCH 098/111] Minor fix: return error when `resource_version` method returns empty hash --- Library/Homebrew/livecheck/livecheck.rb | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 0195e2f7a7..b7c5b7c8c2 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -251,13 +251,22 @@ module Homebrew if check_for_resources resource_version_info = formula_or_cask.resources.map do |resource| res_skip_info ||= SkipConditions.skip_information(resource, verbose: verbose) - res_skip_info.presence || resource_version( - resource, - json: json, - verbose: verbose, - debug: debug, - ) - end.compact + if res_skip_info.present? + res_skip_info + else + res_version_info = resource_version( + resource, + json: json, + verbose: verbose, + debug: debug, + ) + if res_version_info.empty? + status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) + else + res_version_info + end + end + end.compact_blank end skip_info ||= SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose) @@ -704,6 +713,7 @@ module Homebrew next end end + puts if debug && strategy.blank? next if strategy.blank? strategy_data = strategy.find_versions( From 980538b8b269392d877244db81ce0b5276a38e7c Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 18 Sep 2022 17:29:44 +0200 Subject: [PATCH 099/111] Exclude `:meta` info for resources if `latest.blank?` for Formula --- Library/Homebrew/livecheck/livecheck.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index b7c5b7c8c2..cbf18e5a75 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -318,7 +318,10 @@ module Homebrew latest_info = status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, verbose: verbose) - latest_info[:resources] = resource_version_info if check_for_resources + if check_for_resources + resource_version_info.map! { |r| r.except!(:meta) } unless verbose + latest_info[:resources] = resource_version_info + end next latest_info end From ee1210a495eea3163b95f21df48933a7aa4de913 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 18 Sep 2022 21:27:10 +0200 Subject: [PATCH 100/111] Fixed style and typecheck issues --- Library/Homebrew/livecheck/livecheck.rb | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index cbf18e5a75..60af738a6e 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -157,6 +157,8 @@ module Homebrew # Executes the livecheck logic for each formula/cask in the # `formulae_and_casks_to_check` array and prints the results. + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity sig { params( formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], @@ -406,6 +408,8 @@ module Homebrew puts JSON.pretty_generate(formulae_checked.compact) end + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) } def package_or_resource_name(package_or_resource, full_name: false) @@ -492,10 +496,10 @@ module Homebrew end # Prints the livecheck result for a resources for a given Formula. - sig { params(info: Hash, verbose: T::Boolean).void } + sig { params(info: T::Array[Hash], verbose: T::Boolean).void } def print_resources_info(info, verbose: false) info.each do |r_info| - if r_info.is_a?(Hash) && r_info[:status] && r_info[:messages] + if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) else print_latest_version( @@ -598,29 +602,29 @@ module Homebrew url end - # livecheck should fetch a URL using brewed curl if the formula/resource/cask + # livecheck should fetch a URL using brewed curl if the formula/cask # contains a `stable`/`url` or `head` URL `using: :homebrew_curl` that # shares the same root domain. - sig { params(package_or_resource: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } - def use_homebrew_curl?(package_or_resource, url) + sig { params(formula_or_cask: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } + def use_homebrew_curl?(formula_or_cask, url) url_root_domain = Addressable::URI.parse(url)&.domain return false if url_root_domain.blank? # Collect root domains of URLs with `using: :homebrew_curl` homebrew_curl_root_domains = [] - case package_or_resource + case formula_or_cask when Formula [:stable, :head].each do |spec_name| - next unless (spec = package_or_resource.send(spec_name)) + next unless (spec = formula_or_cask.send(spec_name)) next unless spec.using == :homebrew_curl domain = Addressable::URI.parse(spec.url)&.domain homebrew_curl_root_domains << domain if domain.present? end when Cask::Cask - return false unless package_or_resource.url.using == :homebrew_curl + return false unless formula_or_cask.url.using == :homebrew_curl - domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain + domain = Addressable::URI.parse(formula_or_cask.url.to_s)&.domain homebrew_curl_root_domains << domain if domain.present? end From 560680bfa3f60bcf7e5ec3800c043303277c2f3d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 18 Sep 2022 21:36:22 +0200 Subject: [PATCH 101/111] Minor fix for `brew typecheck` --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 60af738a6e..1b3ec421f4 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -640,7 +640,7 @@ module Homebrew json: T::Boolean, verbose: T::Boolean, debug: T::Boolean, - ).returns(T.nilable(Hash)) + ).returns(Hash) } def resource_version( resource, From 6d993fa642c9126e01662f0c1daa75b281371efa Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 25 Sep 2022 00:53:44 +0200 Subject: [PATCH 102/111] Fixed minor issues and applied suggestions --- Library/Homebrew/livecheck/livecheck.rb | 401 ++++++++++++------------ 1 file changed, 202 insertions(+), 199 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 1b3ec421f4..e50aac01e0 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -259,8 +259,9 @@ module Homebrew res_version_info = resource_version( resource, json: json, - verbose: verbose, debug: debug, + quiet: quiet, + verbose: verbose, ) if res_version_info.empty? status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) @@ -389,9 +390,9 @@ module Homebrew onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}" $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) + print_resources_info(resource_version_info, verbose: verbose) if check_for_resources nil end - print_resources_info(resource_version_info, verbose: verbose) if check_for_resources end # rubocop:enable Metrics/BlockLength @@ -501,6 +502,7 @@ module Homebrew info.each do |r_info| if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) + Homebrew.failed = true else print_latest_version( r_info, @@ -539,8 +541,6 @@ module Homebrew urls = [] case package_or_resource - when Resource - urls << package_or_resource.url when Formula if package_or_resource.stable urls << package_or_resource.stable.url @@ -552,6 +552,8 @@ module Homebrew urls << package_or_resource.appcast.to_s if package_or_resource.appcast urls << package_or_resource.url.to_s if package_or_resource.url urls << package_or_resource.homepage if package_or_resource.homepage + when Resource + urls << package_or_resource.url else T.absurd(package_or_resource) end @@ -631,199 +633,6 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end - # Identifies the latest version of the resource in a given Formulae and returns a Hash containing - # the version information for a resource. Returns a nil value if a latest version - # couldn't be found for a given resource. - sig { - params( - resource: Resource, - json: T::Boolean, - verbose: T::Boolean, - debug: T::Boolean, - ).returns(Hash) - } - def resource_version( - resource, - json: false, - verbose: false, - debug: false - ) - has_livecheckable = resource.livecheckable? - - if debug - puts "\n\n" - puts "Resource: #{resource.name}" - puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" - end - - resource_version_info = {} - - livecheck = resource.livecheck - livecheck_url = has_livecheckable ? livecheck.url : resource.url - livecheck_regex = livecheck&.regex - livecheck_strategy = livecheck&.strategy - livecheck_strategy_block = livecheck&.strategy_block - - livecheck_url_string = livecheck_url_to_string( - livecheck_url, - resource, - ) - - urls = [livecheck_url_string] if livecheck_url_string - urls ||= checkable_urls(resource) - - checked_urls = [] - - # rubocop:disable Metrics/BlockLength - urls.each_with_index do |original_url, i| - # Only preprocess the URL when it's appropriate - url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) - original_url - else - preprocess_url(original_url) - end - next if checked_urls.include?(url) - - strategies = Strategy.from_url( - url, - livecheck_strategy: livecheck_strategy, - url_provided: livecheck_url.present?, - regex_provided: livecheck_regex.present?, - block_provided: livecheck_strategy_block.present?, - ) - - strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first - strategy_name = livecheck_strategy_names[strategy] - - if debug - puts - if livecheck_url.is_a?(Symbol) - # This assumes the URL symbol will fit within the available space - puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url - else - puts "URL: #{original_url}" - end - puts "URL (processed): #{url}" if url != original_url - if strategies.present? && verbose - puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" - end - puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" - puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? - end - - if livecheck_strategy.present? - if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) - odebug "#{strategy_name} strategy requires a URL" - next - elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) - odebug "#{strategy_name} strategy does not apply to this URL" - next - end - end - puts if debug && strategy.blank? - next if strategy.blank? - - strategy_data = strategy.find_versions( - url: url, regex: livecheck_regex, - homebrew_curl: false, &livecheck_strategy_block - ) - match_version_map = strategy_data[:matches] - regex = strategy_data[:regex] - messages = strategy_data[:messages] - checked_urls << url - - if messages.is_a?(Array) && match_version_map.blank? - puts messages unless json - next if i + 1 < urls.length - - return status_hash(resource, "error", messages, verbose: verbose) - end - - if debug - if strategy_data[:url].present? && strategy_data[:url] != url - puts "URL (strategy): #{strategy_data[:url]}" - end - puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? - if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex - puts "Regex (strategy): #{strategy_data[:regex].inspect}" - end - puts "Cached?: Yes" if strategy_data[:cached] == true - end - - match_version_map.delete_if do |_match, version| - next true if version.blank? - next false if has_livecheckable - - UNSTABLE_VERSION_KEYWORDS.any? do |rejection| - version.to_s.include?(rejection) - end - end - next if match_version_map.blank? - - if debug - puts - puts "Matched Versions:" - - if verbose - match_version_map.each do |match, version| - puts "#{match} => #{version.inspect}" - end - else - puts match_version_map.values.join(", ") - end - end - - res_current = resource.version - res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) - - return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) if res_latest.to_s.blank? - - is_newer_than_upstream = res_current > res_latest - is_outdated = (res_current != res_latest) && !is_newer_than_upstream - - resource_version_info = { - resource: resource.name, - version: { - current: res_current.to_s, - latest: res_latest.to_s, - newer_than_upstream: is_newer_than_upstream, - outdated: is_outdated, - }, - } - - resource_version_info[:meta] = { url: { original: original_url } } - resource_version_info[:meta][:url][:processed] = url if url != original_url - resource_version_info[:meta][:livecheckable] = has_livecheckable - next unless has_livecheckable - - res_livecheck = { url: { original: livecheck_url } } - res_livecheck[:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string - if strategy_data[:url].present? && strategy_data[:url] != url - res_livecheck[:url][:strategy] = strategy_data[:url] - end - res_livecheck[:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - res_livecheck[:strategy] = strategy.present? ? strategy_name : nil - if strategies.present? - res_livecheck[:strategies] = strategies.map do |s| - livecheck_strategy_names[s] - end - end - res_livecheck[:regex] = regex.inspect if regex.present? - res_livecheck[:cached] = true if strategy_data[:cached] == true - resource_version_info[:meta][:livecheck] = res_livecheck - rescue => e - Homebrew.failed = true - if json - status_hash(resource, "error", [e.to_s], verbose: verbose) - elsif onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}" - $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) - nil - end - end - # rubocop:enable Metrics/BlockLength - resource_version_info - end - # Identifies the latest version of the formula/cask and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. # rubocop:disable Metrics/CyclomaticComplexity @@ -945,7 +754,6 @@ module Homebrew cask: cask, &livecheck_strategy_block ) - match_version_map = strategy_data[:matches] regex = strategy_data[:regex] messages = strategy_data[:messages] @@ -994,7 +802,6 @@ module Homebrew end version_info = { - # latest: {}, latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), } @@ -1035,6 +842,202 @@ module Homebrew nil end # rubocop:enable Metrics/CyclomaticComplexity + + # Identifies the latest version of the resource in a given Formulae and returns a Hash containing + # the version information for a resource. Returns a nil value if a latest version + # couldn't be found for a given resource. + sig { + params( + resource: Resource, + json: T::Boolean, + debug: T::Boolean, + quiet: T::Boolean, + verbose: T::Boolean, + ).returns(Hash) + } + def resource_version( + resource, + json: false, + debug: false, + quiet: false, + verbose: false + ) + has_livecheckable = resource.livecheckable? + + if debug + puts "\n\n" + puts "Resource: #{resource.name}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + end + + resource_version_info = {} + + livecheck = resource.livecheck + livecheck_url = has_livecheckable ? livecheck.url : resource.url + livecheck_regex = livecheck.regex + livecheck_strategy = livecheck.strategy + livecheck_strategy_block = livecheck.strategy_block + + livecheck_url_string = livecheck_url_to_string( + livecheck_url, + resource, + ) + + urls = [livecheck_url_string] if livecheck_url_string + urls ||= checkable_urls(resource) + + checked_urls = [] + + # rubocop:disable Metrics/BlockLength + urls.each_with_index do |original_url, i| + # Only preprocess the URL when it's appropriate + url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + original_url + else + preprocess_url(original_url) + end + next if checked_urls.include?(url) + + strategies = Strategy.from_url( + url, + livecheck_strategy: livecheck_strategy, + url_provided: livecheck_url.present?, + regex_provided: livecheck_regex.present?, + block_provided: livecheck_strategy_block.present?, + ) + + strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + strategy_name = livecheck_strategy_names[strategy] + + if debug + puts + if livecheck_url.is_a?(Symbol) + # This assumes the URL symbol will fit within the available space + puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url + else + puts "URL: #{original_url}" + end + puts "URL (processed): #{url}" if url != original_url + if strategies.present? && verbose + puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" + end + puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + end + + if livecheck_strategy.present? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + odebug "#{strategy_name} strategy requires a URL" + next + elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + odebug "#{strategy_name} strategy does not apply to this URL" + next + end + end + puts if debug && strategy.blank? + next if strategy.blank? + + strategy_data = strategy.find_versions( + url: url, regex: livecheck_regex, + homebrew_curl: false, &livecheck_strategy_block + ) + match_version_map = strategy_data[:matches] + regex = strategy_data[:regex] + messages = strategy_data[:messages] + checked_urls << url + + if messages.is_a?(Array) && match_version_map.blank? + puts messages unless json + next if i + 1 < urls.length + + return status_hash(resource, "error", messages, verbose: verbose) + end + + if debug + if strategy_data[:url].present? && strategy_data[:url] != url + puts "URL (strategy): #{strategy_data[:url]}" + end + puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + puts "Regex (strategy): #{strategy_data[:regex].inspect}" + end + puts "Cached?: Yes" if strategy_data[:cached] == true + end + + match_version_map.delete_if do |_match, version| + next true if version.blank? + next false if has_livecheckable + + UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + version.to_s.include?(rejection) + end + end + next if match_version_map.blank? + + if debug + puts + puts "Matched Versions:" + + if verbose + match_version_map.each do |match, version| + puts "#{match} => #{version.inspect}" + end + else + puts match_version_map.values.join(", ") + end + end + + res_current = resource.version + res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) + + return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) if res_latest.blank? + + is_outdated = res_current < res_latest + is_newer_than_upstream = res_current > res_latest + + resource_version_info = { + resource: resource.name, + version: { + current: res_current.to_s, + latest: res_latest.to_s, + outdated: is_outdated, + newer_than_upstream: is_newer_than_upstream, + }, + } + + resource_version_info[:meta] = { livecheckable: has_livecheckable, url: {} } + if livecheck_url.is_a?(Symbol) && livecheck_url_string + resource_version_info[:meta][:url][:symbol] = + livecheck_url + end + resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url][:processed] = url if url != original_url + if strategy_data[:url].present? && strategy_data[:url] != url + resource_version_info[:meta][:url][:strategy] = strategy_data[:url] + end + resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil + if strategies.present? + resource_version_info[:meta][:strategies] = strategies.map do |s| + livecheck_strategy_names[s] + end + end + resource_version_info[:meta][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true + + rescue => e + Homebrew.failed = true + if json + status_hash(resource, "error", [e.to_s], verbose: verbose) + elsif !quiet + onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}" + $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) + nil + end + end + # rubocop:enable Metrics/BlockLength + resource_version_info + end end # rubocop:enable Metrics/ModuleLength end From 03c372ef52fa2fffe6d8677f563ddbcf1f95c714 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 25 Sep 2022 02:06:23 +0200 Subject: [PATCH 103/111] Minor fixes --- Library/Homebrew/livecheck/skip_conditions.rb | 6 +++--- Library/Homebrew/test/livecheck/livecheck_spec.rb | 14 ++++---------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index 7991f2d07d..3e1fefe3f6 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -33,7 +33,7 @@ module Homebrew stable_from_internet_archive = stable_url.match?(%r{https?://web\.archive\.org/}i) end - skip_message = if package_or_resource.livecheck&.skip_msg.present? + skip_message = if package_or_resource.livecheck.skip_msg.present? package_or_resource.livecheck.skip_msg elsif !livecheckable if stable_from_google_code_archive @@ -45,7 +45,7 @@ module Homebrew end end - return {} if !package_or_resource.livecheck&.skip? && skip_message.blank? + return {} if !package_or_resource.livecheck.skip? && skip_message.blank? skip_messages = skip_message ? [skip_message] : nil Livecheck.status_hash(package_or_resource, "skipped", skip_messages, full_name: full_name, verbose: verbose) @@ -172,7 +172,7 @@ module Homebrew :cask_url_unversioned, ].freeze - # Skip conditions for resource + # Skip conditions for resource. RESOURCE_CHECKS = [ :package_or_resource_skip, ].freeze diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index bb43d2b7da..fdc076dc47 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -11,6 +11,7 @@ describe Homebrew::Livecheck do let(:homepage_url) { "https://brew.sh" } let(:livecheck_url) { "https://formulae.brew.sh/api/formula/ruby.json" } let(:stable_url) { "https://brew.sh/test-0.0.1.tgz" } + let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" } let(:f) do formula("test") do @@ -116,6 +117,7 @@ describe Homebrew::Livecheck do homepage_url_s = homepage_url stable_url_s = stable_url head_url_s = head_url + resource_url_s = resource_url formula("test_livecheck_url") do desc "Test Livecheck URL formula" @@ -124,7 +126,7 @@ describe Homebrew::Livecheck do head head_url_s resource "foo" do - url "https://brew.sh/foo-1.0.tar.gz" + url resource_url_s sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" livecheck do @@ -164,15 +166,7 @@ describe Homebrew::Livecheck do expect(livecheck.livecheck_url_to_string(:homepage, c_livecheck_url)).to eq(homepage_url) expect(livecheck.livecheck_url_to_string(:stable, f_livecheck_url)).to eq(stable_url) expect(livecheck.livecheck_url_to_string(:url, c_livecheck_url)).to eq(cask_url) - - r_livecheck_url.livecheck.url(:url) - expect(livecheck.livecheck_url_to_string(cask_url, r_livecheck_url)).to eq(cask_url) - - r_livecheck_url.livecheck.url(:head) - expect(livecheck.livecheck_url_to_string(head_url, r_livecheck_url)).to eq(head_url) - - r_livecheck_url.livecheck.url(:stable) - expect(livecheck.livecheck_url_to_string(stable_url, r_livecheck_url)).to eq(stable_url) + expect(livecheck.livecheck_url_to_string(:url, r_livecheck_url)).to eq(resource_url) end it "returns nil when not given a string or valid symbol" do From 2f74eb5b5b1172e8ecfb0fc03f3f3ddfc5e3ff8c Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 25 Sep 2022 22:21:04 +0500 Subject: [PATCH 104/111] Update Library/Homebrew/livecheck/livecheck.rb Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e50aac01e0..cb29be0831 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -873,7 +873,7 @@ module Homebrew resource_version_info = {} livecheck = resource.livecheck - livecheck_url = has_livecheckable ? livecheck.url : resource.url + livecheck_url = livecheck.url livecheck_regex = livecheck.regex livecheck_strategy = livecheck.strategy livecheck_strategy_block = livecheck.strategy_block From ae031041a28d12ba7da987ed7ca7161a9b925a07 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 25 Sep 2022 20:48:44 +0200 Subject: [PATCH 105/111] Refactored code --- Library/Homebrew/livecheck/livecheck.rb | 54 ++++++++++++------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e50aac01e0..f49d9e0e7c 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -247,37 +247,11 @@ module Homebrew ) end - # Check current and latest resources (if "--resources" flag is given) - # Only check current and latest versions if we have resources to check against - check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - if check_for_resources - resource_version_info = formula_or_cask.resources.map do |resource| - res_skip_info ||= SkipConditions.skip_information(resource, verbose: verbose) - if res_skip_info.present? - res_skip_info - else - res_version_info = resource_version( - resource, - json: json, - debug: debug, - quiet: quiet, - verbose: verbose, - ) - if res_version_info.empty? - status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) - else - res_version_info - end - end - end.compact_blank - end - skip_info ||= SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose) if skip_info.present? next skip_info if json && !newer_only SkipConditions.print_skip_information(skip_info) if !newer_only && !quiet - print_resources_info(resource_version_info, verbose: verbose) if check_for_resources next end @@ -312,6 +286,31 @@ module Homebrew version_info[:latest] if version_info.present? end + # Check current and latest resources (if "--resources" flag is given) + # Only check current and latest versions if we have resources to check against + check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? + if check_for_resources + resource_version_info = formula_or_cask.resources.map do |resource| + res_skip_info ||= SkipConditions.skip_information(resource, verbose: verbose) + if res_skip_info.present? + res_skip_info + else + res_version_info = resource_version( + resource, + json: json, + debug: debug, + quiet: quiet, + verbose: verbose, + ) + if res_version_info.empty? + status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) + else + res_version_info + end + end + end.compact_blank + end + if latest.blank? no_versions_msg = "Unable to get versions" raise Livecheck::Error, no_versions_msg unless json @@ -526,9 +525,6 @@ module Homebrew when :url package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable - # Since resource's "url" is considered "stable" by default. - # And some resources may contain in "head" block as well - package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage package_or_resource.homepage unless package_or_resource.is_a?(Resource) From e3cab15e935233ea5de0420a76c16dae3f80ba2f Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 26 Sep 2022 19:37:46 +0200 Subject: [PATCH 106/111] Set `Homebrew.failed = true` to get correct status code --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 4e6d346700..9c7c4131d3 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -309,6 +309,7 @@ module Homebrew end end end.compact_blank + Homebrew.failed = true if resource_version_info.any? { |info| info[:status] == "error" } end if latest.blank? @@ -501,7 +502,6 @@ module Homebrew info.each do |r_info| if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) - Homebrew.failed = true else print_latest_version( r_info, From 40b0070bebf6ef34435ebd521c14c5a3770fca34 Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:18:20 -0400 Subject: [PATCH 107/111] Modify comments and other text The `check_for_resources` code arguably speaks for itself, so it doesn't feel like a necessary addition. Besides that, this cleans up some other comments and text to better align with existing examples. --- Library/Homebrew/livecheck/livecheck.rb | 4 +--- Library/Homebrew/livecheck/skip_conditions.rb | 2 +- Library/Homebrew/test/livecheck/livecheck_spec.rb | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 9c7c4131d3..bacc7a638d 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -286,8 +286,6 @@ module Homebrew version_info[:latest] if version_info.present? end - # Check current and latest resources (if "--resources" flag is given) - # Only check current and latest versions if we have resources to check against check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? if check_for_resources resource_version_info = formula_or_cask.resources.map do |resource| @@ -531,7 +529,7 @@ module Homebrew end end - # Returns an Array containing the formula/resource/cask URLs that can be used by livecheck. + # Returns an Array containing the formula/cask/resource URLs that can be used by livecheck. sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource)).returns(T::Array[String]) } def checkable_urls(package_or_resource) urls = [] diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index 3e1fefe3f6..be5159cb97 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -172,7 +172,7 @@ module Homebrew :cask_url_unversioned, ].freeze - # Skip conditions for resource. + # Skip conditions for resources. RESOURCE_CHECKS = [ :package_or_resource_skip, ].freeze diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index fdc076dc47..c23f2391b9 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -152,11 +152,11 @@ describe Homebrew::Livecheck do RUBY end - it "returns a URL string when given a livecheck_url string for formula" do + it "returns a URL string when given a livecheck_url string for a formula" do expect(livecheck.livecheck_url_to_string(livecheck_url, f_livecheck_url)).to eq(livecheck_url) end - it "returns a URL string when given a livecheck_url string for resource" do + it "returns a URL string when given a livecheck_url string for a resource" do expect(livecheck.livecheck_url_to_string(livecheck_url, r_livecheck_url)).to eq(livecheck_url) end From 7ffeba6380035e190efdf7eb7a003dd51e356cea Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:21:18 -0400 Subject: [PATCH 108/111] Convert some multiline code into a single line Using a multiline format in these areas isn't necessary and we can clean up these lines by converting them to a single line format. --- Library/Homebrew/livecheck/livecheck.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bacc7a638d..44e1a15f68 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -872,10 +872,7 @@ module Homebrew livecheck_strategy = livecheck.strategy livecheck_strategy_block = livecheck.strategy_block - livecheck_url_string = livecheck_url_to_string( - livecheck_url, - resource, - ) + livecheck_url_string = livecheck_url_to_string(livecheck_url, resource) urls = [livecheck_url_string] if livecheck_url_string urls ||= checkable_urls(resource) @@ -1001,8 +998,7 @@ module Homebrew resource_version_info[:meta] = { livecheckable: has_livecheckable, url: {} } if livecheck_url.is_a?(Symbol) && livecheck_url_string - resource_version_info[:meta][:url][:symbol] = - livecheck_url + resource_version_info[:meta][:url][:symbol] = livecheck_url end resource_version_info[:meta][:url][:original] = original_url resource_version_info[:meta][:url][:processed] = url if url != original_url From fb653c00d8152da765b56c0bb1ae7bba5bf7002d Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:27:26 -0400 Subject: [PATCH 109/111] Improve consistency of *_version methods Minimizing the differences between the `#resource_version` and `#latest_version` methods will help to ease the process of potentially merging them into one method in the future. --- Library/Homebrew/livecheck/livecheck.rb | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 44e1a15f68..722297ddbb 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -779,7 +779,6 @@ module Homebrew version.to_s.include?(rejection) end end - next if match_version_map.blank? if debug @@ -878,7 +877,6 @@ module Homebrew urls ||= checkable_urls(resource) checked_urls = [] - # rubocop:disable Metrics/BlockLength urls.each_with_index do |original_url, i| # Only preprocess the URL when it's appropriate @@ -896,7 +894,6 @@ module Homebrew regex_provided: livecheck_regex.present?, block_provided: livecheck_strategy_block.present?, ) - strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first strategy_name = livecheck_strategy_names[strategy] @@ -929,8 +926,10 @@ module Homebrew next if strategy.blank? strategy_data = strategy.find_versions( - url: url, regex: livecheck_regex, - homebrew_curl: false, &livecheck_strategy_block + url: url, + regex: livecheck_regex, + homebrew_curl: false, + &livecheck_strategy_block ) match_version_map = strategy_data[:matches] regex = strategy_data[:regex] @@ -1008,9 +1007,7 @@ module Homebrew resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil if strategies.present? - resource_version_info[:meta][:strategies] = strategies.map do |s| - livecheck_strategy_names[s] - end + resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } end resource_version_info[:meta][:regex] = regex.inspect if regex.present? resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true From bd9c436d50c71eef58b3f9ba511e701cf27b377c Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:36:33 -0400 Subject: [PATCH 110/111] Remove unnecessary parameter from method A boolean `resource` parameter was added to `#print_latest_version` but its only purpose is to identify whether `info` corresponds to a resource. This can be achieved using `info[:resource].present?`, so this additional parameter isn't necessary and can be removed. --- Library/Homebrew/livecheck/livecheck.rb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 722297ddbb..086b4cfcd8 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -472,9 +472,9 @@ module Homebrew end # Formats and prints the livecheck result for a formula/cask/resource. - sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } - def print_latest_version(info, verbose: false, ambiguous_cask: false, resource: false) - package_or_resource_s = resource ? " " : "" + sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void } + def print_latest_version(info, verbose: false, ambiguous_cask: false) + package_or_resource_s = info[:resource].present? ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable] @@ -501,11 +501,7 @@ module Homebrew if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) else - print_latest_version( - r_info, - verbose: verbose, - resource: true, - ) + print_latest_version(r_info, verbose: verbose) end end end From b5c88419808c82983869ed09ecedfae3656bfe17 Mon Sep 17 00:00:00 2001 From: Nanda H Krishna Date: Tue, 27 Sep 2022 00:59:37 -0700 Subject: [PATCH 111/111] Modified text in comments --- Library/Homebrew/livecheck/livecheck.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 086b4cfcd8..f4ae28f06a 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -494,7 +494,7 @@ module Homebrew puts "#{package_or_resource_s}: #{current_s} ==> #{latest_s}" end - # Prints the livecheck result for a resources for a given Formula. + # Prints the livecheck result for the resources of a given Formula. sig { params(info: T::Array[Hash], verbose: T::Boolean).void } def print_resources_info(info, verbose: false) info.each do |r_info| @@ -832,9 +832,8 @@ module Homebrew end # rubocop:enable Metrics/CyclomaticComplexity - # Identifies the latest version of the resource in a given Formulae and returns a Hash containing - # the version information for a resource. Returns a nil value if a latest version - # couldn't be found for a given resource. + # Identifies the latest version of a resource and returns a Hash containing the + # version information. Returns nil if a latest version couldn't be found. sig { params( resource: Resource,