packwerk_yard 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +1 -1
  4. data/Rakefile +5 -1
  5. data/lib/packwerk_yard/parser.rb +19 -10
  6. data/lib/packwerk_yard/version.rb +2 -2
  7. data/lib/packwerk_yard.rb +1 -1
  8. data/sorbet/config +4 -0
  9. data/sorbet/rbi/annotations/.gitattributes +1 -0
  10. data/sorbet/rbi/annotations/actionview.rbi +75 -0
  11. data/sorbet/rbi/annotations/activesupport.rbi +264 -0
  12. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  13. data/sorbet/rbi/gems/.gitattributes +1 -0
  14. data/sorbet/rbi/gems/actionview@7.1.2.rbi +15002 -0
  15. data/sorbet/rbi/gems/activesupport@7.1.2.rbi +18797 -0
  16. data/sorbet/rbi/gems/ast@2.4.2.rbi +584 -0
  17. data/sorbet/rbi/gems/base64@0.2.0.rbi +508 -0
  18. data/sorbet/rbi/gems/better_html@2.0.2.rbi +529 -0
  19. data/sorbet/rbi/gems/bigdecimal@3.1.5.rbi +77 -0
  20. data/sorbet/rbi/gems/builder@3.2.4.rbi +8 -0
  21. data/sorbet/rbi/gems/concurrent-ruby@1.2.2.rbi +11545 -0
  22. data/sorbet/rbi/gems/connection_pool@2.4.1.rbi +8 -0
  23. data/sorbet/rbi/gems/constant_resolver@0.2.0.rbi +90 -0
  24. data/sorbet/rbi/gems/crass@1.0.6.rbi +622 -0
  25. data/sorbet/rbi/gems/drb@2.2.0.rbi +1346 -0
  26. data/sorbet/rbi/gems/erubi@1.12.0.rbi +145 -0
  27. data/sorbet/rbi/gems/i18n@1.14.1.rbi +2325 -0
  28. data/sorbet/rbi/gems/json@2.7.1.rbi +1561 -0
  29. data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +14237 -0
  30. data/sorbet/rbi/gems/loofah@2.22.0.rbi +1080 -0
  31. data/sorbet/rbi/gems/minitest@5.20.0.rbi +1497 -0
  32. data/sorbet/rbi/gems/mutex_m@0.2.0.rbi +93 -0
  33. data/sorbet/rbi/gems/netrc@0.11.0.rbi +158 -0
  34. data/sorbet/rbi/gems/nokogiri@1.16.0.rbi +7286 -0
  35. data/sorbet/rbi/gems/packwerk@3.1.0-bf972227a1caaeed4d07b0302a7b74f20632fc06.rbi +2370 -0
  36. data/sorbet/rbi/gems/parallel@1.24.0.rbi +280 -0
  37. data/sorbet/rbi/gems/parser@3.2.2.4.rbi +7253 -0
  38. data/sorbet/rbi/gems/prettier_print@1.2.1.rbi +951 -0
  39. data/sorbet/rbi/gems/prism@0.19.0.rbi +29883 -0
  40. data/sorbet/rbi/gems/racc@1.7.3.rbi +161 -0
  41. data/sorbet/rbi/gems/rails-dom-testing@2.2.0.rbi +8 -0
  42. data/sorbet/rbi/gems/rails-html-sanitizer@1.6.0.rbi +716 -0
  43. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +402 -0
  44. data/sorbet/rbi/gems/rake@13.1.0.rbi +3045 -0
  45. data/sorbet/rbi/gems/rbi@0.1.6.rbi +2922 -0
  46. data/sorbet/rbi/gems/regexp_parser@2.8.3.rbi +3749 -0
  47. data/sorbet/rbi/gems/rexml@3.2.6.rbi +4781 -0
  48. data/sorbet/rbi/gems/rubocop-ast@1.30.0.rbi +7099 -0
  49. data/sorbet/rbi/gems/rubocop-performance@1.20.1.rbi +3248 -0
  50. data/sorbet/rbi/gems/rubocop-shopify@2.14.0.rbi +8 -0
  51. data/sorbet/rbi/gems/rubocop-sorbet@0.7.6.rbi +1510 -0
  52. data/sorbet/rbi/gems/rubocop@1.59.0.rbi +57240 -0
  53. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1317 -0
  54. data/sorbet/rbi/gems/ruby2_keywords@0.0.5.rbi +8 -0
  55. data/sorbet/rbi/gems/smart_properties@1.17.0.rbi +474 -0
  56. data/sorbet/rbi/gems/spoom@1.2.4.rbi +3777 -0
  57. data/sorbet/rbi/gems/syntax_tree@6.2.0.rbi +23136 -0
  58. data/sorbet/rbi/gems/tapioca@0.11.14.rbi +3509 -0
  59. data/sorbet/rbi/gems/thor@1.3.0.rbi +4345 -0
  60. data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5917 -0
  61. data/sorbet/rbi/gems/unicode-display_width@2.5.0.rbi +65 -0
  62. data/sorbet/rbi/gems/yard-sorbet@0.8.1.rbi +428 -0
  63. data/sorbet/rbi/gems/yard@0.9.34.rbi +18219 -0
  64. data/sorbet/rbi/gems/zeitwerk@2.6.12.rbi +8 -0
  65. data/sorbet/rbi/todo.rbi +7 -0
  66. data/sorbet/tapioca/config.yml +13 -0
  67. data/sorbet/tapioca/require.rb +4 -0
  68. metadata +75 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 641e8d0ddb1071b14b67085d3b9ab52fe72aac4b49d96909ae43b76212254e3f
4
- data.tar.gz: 3243f067d6d129efde447741ee15257acd184214ec42edbca3ef58aa4d12fe83
3
+ metadata.gz: e9a27f1f2b9a3c3610fe647c7be7b46e917717d9a341ded7c10c93c8146b0b9c
4
+ data.tar.gz: 4ec873d282498c7577be575a54bc8e99546b0023bbced4670c92fdb9c69259b3
5
5
  SHA512:
6
- metadata.gz: 6e5272b9c7c1fa88234dedce138a5fd1bc15ddb6a7b98ef351741b7061ffee20a0198ab1765bc5517a5560d9c1f2cb44d5095cb7b3304fb7ca6e4a9d73844bee
7
- data.tar.gz: bc151f151c15c7bd7d64acb0b8c6f9c8768b79eccbee85326c4d501dea284203e525719f63a837c92933e6d01a4146a2a40d2f861a91c6df643b8f4134f64b1e
6
+ metadata.gz: 800d9e2a2e50d44f3aaaeb671a27790f7ad5c4e27503fd647e4ae84f3b1d98c53e06b3fb88d43d9d10f295e280323fc951081fe0cf44f240aa86ecaf3e6acfa7
7
+ data.tar.gz: a771a4fc12e32723c15a395b9388b99350f469c66a9aff34a1208f28b394f5078a4efc1b197f42d5dc609c69f7e59026fb644648748601c88111da006e867649
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2024-01-07
4
+
5
+ - Add packwerk to dependencies https://github.com/euglena1215/packwerk-yard/pull/6
6
+ - Introduce sorbet https://github.com/euglena1215/packwerk-yard/pull/7
7
+ - Support nested array & nested hash https://github.com/euglena1215/packwerk-yard/pull/8
8
+
3
9
  ## [0.1.0] - 2024-01-07
4
10
 
5
11
  - Initial release
data/README.md CHANGED
@@ -11,7 +11,7 @@ Add YARD support to packwerk.
11
11
  1. Add this line to your application's Gemfile:
12
12
 
13
13
  ```ruby
14
- gem 'packwerk_yard', github: 'euglena1215/packwerk-yard', group: :development
14
+ gem 'packwerk_yard', require: false, group: :development
15
15
  ```
16
16
 
17
17
  2. Require `packwerk-yard` in your `packwerk.yml`
data/Rakefile CHANGED
@@ -9,4 +9,8 @@ require "rubocop/rake_task"
9
9
 
10
10
  RuboCop::RakeTask.new
11
11
 
12
- task default: [:test, :rubocop]
12
+ task :sorbet do
13
+ sh "bundle exec srb tc"
14
+ end
15
+
16
+ task default: [:test, :rubocop, :sorbet]
@@ -1,18 +1,25 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module PackwerkYard
5
5
  class Parser
6
+ extend T::Sig
6
7
  include Packwerk::FileParser
7
8
 
8
9
  # Array Syntax e.g. Array<String>
9
- ARRAY_REGEXP = /Array<(.+)>/.freeze
10
+ ARRAY_REGEXP = T.let(/\AArray<(.+)>/.freeze, Regexp)
10
11
  private_constant :ARRAY_REGEXP
11
12
 
13
+ # Hash Syntax e.g. Hash<String, String>
14
+ HASH_REGEXP = T.let(/\AHash<([^,]*),\s?(.*)>/.freeze, Regexp)
15
+ private_constant :HASH_REGEXP
16
+
17
+ sig { params(ruby_parser: T.nilable(Packwerk::Parsers::Ruby)).void }
12
18
  def initialize(ruby_parser: Packwerk::Parsers::Ruby.new)
13
19
  @ruby_parser = ruby_parser
14
20
  end
15
21
 
22
+ sig { override.params(io: T.any(IO, StringIO), file_path: String).returns(T.untyped) }
16
23
  def call(io:, file_path: "<unknown>")
17
24
  source_code = io.read
18
25
  return to_ruby_ast(nil.inspect, file_path) if source_code.nil?
@@ -20,19 +27,21 @@ module PackwerkYard
20
27
  types = extract_from_yard_to_types(source_code)
21
28
 
22
29
  to_ruby_ast(
23
- types.map { |type| to_evaluable_type(type) }
30
+ types.map { |type| to_evaluable_type(type) }.flatten
24
31
  .reject { |type| to_constant(type).nil? }
25
32
  .inspect.delete('"'),
26
33
  file_path,
27
34
  )
28
35
  end
29
36
 
37
+ sig { override.params(path: String).returns(T::Boolean) }
30
38
  def match?(path:)
31
39
  path.end_with?(".rb")
32
40
  end
33
41
 
34
42
  private
35
43
 
44
+ sig { params(source_code: String).returns(T::Array[String]) }
36
45
  def extract_from_yard_to_types(source_code)
37
46
  YARD::Registry.clear
38
47
  YARD::Logger.instance.enter_level(YARD::Logger::ERROR) do
@@ -51,23 +60,23 @@ module PackwerkYard
51
60
  types.uniq
52
61
  end
53
62
 
63
+ sig { params(type: String).returns(T::Array[String]) }
54
64
  def to_evaluable_type(type)
55
- # "Array<Integer>" => "Integer"
56
- if type =~ ARRAY_REGEXP
57
- Regexp.last_match(1)
58
- else
59
- type
60
- end
65
+ matched_types = Array(ARRAY_REGEXP.match(type).to_a[1])
66
+ matched_types = Array(HASH_REGEXP.match(type).to_a[1..2]) if matched_types.empty?
67
+ matched_types.empty? ? [type] : matched_types.map { |t| to_evaluable_type(t) }.flatten
61
68
  end
62
69
 
70
+ sig { params(name: T.any(Symbol, String)).returns(T.untyped) }
63
71
  def to_constant(name)
64
72
  Object.const_get(name) # rubocop:disable Sorbet/ConstantsFromStrings
65
73
  rescue NameError
66
74
  nil
67
75
  end
68
76
 
77
+ sig { params(code: String, file_path: T.untyped).returns(T.untyped) }
69
78
  def to_ruby_ast(code, file_path)
70
- @ruby_parser.call(
79
+ T.must(@ruby_parser).call(
71
80
  io: StringIO.new(code),
72
81
  file_path: file_path,
73
82
  )
@@ -1,6 +1,6 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module PackwerkYard
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
data/lib/packwerk_yard.rb CHANGED
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "packwerk"
data/sorbet/config ADDED
@@ -0,0 +1,4 @@
1
+ --dir
2
+ .
3
+ --ignore=tmp/
4
+ --ignore=vendor/
@@ -0,0 +1 @@
1
+ **/*.rbi linguist-vendored=true
@@ -0,0 +1,75 @@
1
+ # typed: true
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This file was pulled from a central RBI files repository.
5
+ # Please run `bin/tapioca annotations` to update it.
6
+
7
+ module ActionView
8
+ TemplateError = T.type_alias { Template::Error }
9
+
10
+ class MissingTemplate < ActionView::ActionViewError
11
+ sig { returns(String) }
12
+ def path; end
13
+ end
14
+ end
15
+
16
+ class ActionView::Helpers::FormBuilder
17
+ sig { returns(T.untyped) }
18
+ def object; end
19
+ end
20
+
21
+ module ActionView::Helpers::NumberHelper
22
+ sig { params(number: T.untyped, options: T::Hash[T.untyped, T.untyped]).returns(T.nilable(String)) }
23
+ def number_to_currency(number, options = T.unsafe(nil)); end
24
+
25
+ sig { params(number: T.untyped, options: T::Hash[T.untyped, T.untyped]).returns(T.nilable(String)) }
26
+ def number_to_human(number, options = T.unsafe(nil)); end
27
+
28
+ sig { params(number: T.untyped, options: T::Hash[T.untyped, T.untyped]).returns(T.nilable(String)) }
29
+ def number_to_human_size(number, options = T.unsafe(nil)); end
30
+
31
+ sig { params(number: T.untyped, options: T::Hash[T.untyped, T.untyped]).returns(T.nilable(String)) }
32
+ def number_to_percentage(number, options = T.unsafe(nil)); end
33
+
34
+ sig { params(number: T.untyped, options: T::Hash[T.untyped, T.untyped]).returns(T.nilable(String)) }
35
+ def number_to_phone(number, options = T.unsafe(nil)); end
36
+
37
+ sig { params(number: T.untyped, options: T::Hash[T.untyped, T.untyped]).returns(T.nilable(String)) }
38
+ def number_with_delimiter(number, options = T.unsafe(nil)); end
39
+
40
+ sig { params(number: T.untyped, options: T::Hash[T.untyped, T.untyped]).returns(T.nilable(String)) }
41
+ def number_with_precision(number, options = T.unsafe(nil)); end
42
+ end
43
+
44
+ module ActionView::Helpers::SanitizeHelper
45
+ mixes_in_class_methods ActionView::Helpers::SanitizeHelper::ClassMethods
46
+ end
47
+
48
+ module ActionView::Helpers::UrlHelper
49
+ extend ActiveSupport::Concern
50
+ include ActionView::Helpers::TagHelper
51
+ mixes_in_class_methods ActionView::Helpers::UrlHelper::ClassMethods
52
+
53
+ sig { params(name: T.nilable(String), options: T.untyped, html_options: T.untyped, block: T.untyped).returns(ActiveSupport::SafeBuffer) }
54
+ def link_to(name = nil, options = nil, html_options = nil, &block); end
55
+
56
+ sig { params(condition: T.untyped, name: String, options: T.untyped, html_options: T.untyped, block: T.untyped).returns(T.untyped) }
57
+ def link_to_if(condition, name, options = {}, html_options = {}, &block); end
58
+ end
59
+
60
+ module ActionView::Layouts
61
+ mixes_in_class_methods ActionView::Layouts::ClassMethods
62
+ end
63
+
64
+ module ActionView::Rendering
65
+ mixes_in_class_methods ActionView::Rendering::ClassMethods
66
+ end
67
+
68
+ module ActionView::ViewPaths
69
+ mixes_in_class_methods ActionView::ViewPaths::ClassMethods
70
+ end
71
+
72
+ module ActionView::ViewPaths::ClassMethods
73
+ sig { params(value: T.any(String, T::Array[String])).void }
74
+ def append_view_path(value); end
75
+ end
@@ -0,0 +1,264 @@
1
+ # typed: true
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This file was pulled from a central RBI files repository.
5
+ # Please run `bin/tapioca annotations` to update it.
6
+
7
+ module ActiveSupport::Testing::Declarative
8
+ sig { params(name: String, block: T.proc.bind(T.untyped).void).void }
9
+ def test(name, &block); end
10
+ end
11
+
12
+ class ActiveSupport::EnvironmentInquirer
13
+ sig { returns(T::Boolean) }
14
+ def development?; end
15
+
16
+ sig { returns(T::Boolean) }
17
+ def production?; end
18
+
19
+ sig { returns(T::Boolean) }
20
+ def test?; end
21
+
22
+ # @method_missing: delegated to String through ActiveSupport::StringInquirer
23
+ sig { returns(T::Boolean) }
24
+ def staging?; end
25
+ end
26
+
27
+ module ActiveSupport::Testing::SetupAndTeardown::ClassMethods
28
+ sig { params(args: T.untyped, block: T.nilable(T.proc.bind(T.untyped).void)).void }
29
+ def setup(*args, &block); end
30
+
31
+ sig { params(args: T.untyped, block: T.nilable(T.proc.bind(T.untyped).void)).void }
32
+ def teardown(*args, &block); end
33
+ end
34
+
35
+ class ActiveSupport::TestCase
36
+ sig { params(args: T.untyped, block: T.nilable(T.proc.bind(T.attached_class).void)).void }
37
+ def self.setup(*args, &block); end
38
+
39
+ sig { params(args: T.untyped, block: T.nilable(T.proc.bind(T.attached_class).void)).void }
40
+ def self.teardown(*args, &block); end
41
+
42
+ sig { params(name: String, block: T.proc.bind(T.attached_class).void).void }
43
+ def self.test(name, &block); end
44
+ end
45
+
46
+ class ActiveSupport::TimeWithZone
47
+ # @shim: Methods on ActiveSupport::TimeWithZone are delegated to `Time` using `method_missing
48
+ include ::DateAndTime::Zones
49
+
50
+ # @shim: Methods on ActiveSupport::TimeWithZone are delegated to `Time` using `method_missing
51
+ include ::DateAndTime::Calculations
52
+
53
+ sig { returns(FalseClass) }
54
+ def blank?; end
55
+
56
+ # @shim: since `present?` is always true, `presence` always returns `self`
57
+ sig { returns(T.self_type) }
58
+ def presence; end
59
+
60
+ # @shim: since `blank?` is always false, `present?` always returns `true`
61
+ sig { returns(TrueClass) }
62
+ def present?; end
63
+ end
64
+
65
+ class Object
66
+ sig { returns(T::Boolean) }
67
+ def blank?; end
68
+
69
+ sig { returns(T.nilable(T.self_type)) }
70
+ def presence; end
71
+
72
+ sig { params(another_object: T.untyped).returns(T.nilable(T.self_type)) }
73
+ def presence_in(another_object); end
74
+
75
+ sig { returns(T::Boolean) }
76
+ def present?; end
77
+ end
78
+
79
+ class Hash
80
+ sig { returns(T::Boolean) }
81
+ def extractable_options?; end
82
+ end
83
+
84
+ class Array
85
+ sig { params(position: Integer).returns(T.self_type) }
86
+ def from(position); end
87
+
88
+ sig { params(position: Integer).returns(T.self_type) }
89
+ def to(position); end
90
+
91
+ sig { params(elements: T.untyped).returns(T::Array[T.untyped]) }
92
+ def including(*elements); end
93
+
94
+ sig { params(elements: T.untyped).returns(T.self_type) }
95
+ def excluding(*elements); end
96
+
97
+ sig { params(elements: T.untyped).returns(T.self_type) }
98
+ def without(*elements); end
99
+
100
+ sig { returns(T.nilable(Elem)) }
101
+ def second; end
102
+
103
+ sig { returns(T.nilable(Elem)) }
104
+ def third; end
105
+
106
+ sig { returns(T.nilable(Elem)) }
107
+ def fourth; end
108
+
109
+ sig { returns(T.nilable(Elem)) }
110
+ def fifth; end
111
+
112
+ sig { returns(T.nilable(Elem)) }
113
+ def forty_two; end
114
+
115
+ sig { returns(T.nilable(Elem)) }
116
+ def third_to_last; end
117
+
118
+ sig { returns(T.nilable(Elem)) }
119
+ def second_to_last; end
120
+
121
+ sig { params(options: T::Hash[T.untyped, T.untyped]).returns(String) }
122
+ def to_sentence(options = {}); end
123
+
124
+ sig { params(format: Symbol).returns(String) }
125
+ def to_fs(format = :default); end
126
+
127
+ sig { params(format: Symbol).returns(String) }
128
+ def to_formatted_s(format = :default); end
129
+
130
+ sig { returns(String) }
131
+ def to_xml; end
132
+
133
+ sig { returns(T::Hash[T.untyped, T.untyped]) }
134
+ def extract_options!; end
135
+
136
+ sig { type_parameters(:FillType).params(number: Integer, fill_with: T.type_parameter(:FillType), block: T.nilable(T.proc.params(group: T::Array[T.any(Elem, T.type_parameter(:FillType))]).void)).returns(T::Array[T::Array[T.any(Elem, T.type_parameter(:FillType))]]) }
137
+ def in_groups(number, fill_with = T.unsafe(nil), &block); end
138
+
139
+ sig { type_parameters(:FillType).params(number: Integer, fill_with: T.type_parameter(:FillType), block: T.nilable(T.proc.params(group: T::Array[T.any(Elem, T.type_parameter(:FillType))]).void)).returns(T::Array[T::Array[T.any(Elem, T.type_parameter(:FillType))]]) }
140
+ def in_groups_of(number, fill_with = T.unsafe(nil), &block); end
141
+
142
+ sig { params(value: T.untyped, block: T.nilable(T.proc.params(element: Elem).returns(T.untyped))).returns(T::Array[T::Array[Elem]]) }
143
+ def split(value = nil, &block); end
144
+
145
+ sig { params(object: T.untyped).returns(T::Array[T.untyped]) }
146
+ def self.wrap(object); end
147
+
148
+ sig { params(block: T.nilable(T.proc.params(element: Elem).returns(T.untyped))).returns(T.any(T::Array[Elem], T::Enumerator[Elem])) }
149
+ def extract!(&block); end
150
+
151
+ sig { returns(ActiveSupport::ArrayInquirer) }
152
+ def inquiry; end
153
+ end
154
+
155
+ class Date
156
+ sig { returns(FalseClass) }
157
+ def blank?; end
158
+
159
+ # @shim: since `present?` is always true, `presence` always returns `self`
160
+ sig { returns(T.self_type) }
161
+ def presence; end
162
+
163
+ # @shim: since `blank?` is always false, `present?` always returns `true`
164
+ sig { returns(TrueClass) }
165
+ def present?; end
166
+ end
167
+
168
+ class DateTime
169
+ sig { returns(FalseClass) }
170
+ def blank?; end
171
+
172
+ # @shim: since `present?` is always true, `presence` always returns `self`
173
+ sig { returns(T.self_type) }
174
+ def presence; end
175
+
176
+ # @shim: since `blank?` is always false, `present?` always returns `true`
177
+ sig { returns(TrueClass) }
178
+ def present?; end
179
+ end
180
+
181
+ class NilClass
182
+ sig { returns(TrueClass) }
183
+ def blank?; end
184
+
185
+ # @shim: since `present?` is always false, `presence` always returns `nil`
186
+ sig { returns(NilClass) }
187
+ def presence; end
188
+
189
+ # @shim: since `blank?` is always true, `present?` always returns `false`
190
+ sig { returns(FalseClass) }
191
+ def present?; end
192
+ end
193
+
194
+ class FalseClass
195
+ sig { returns(TrueClass) }
196
+ def blank?; end
197
+
198
+ # @shim: since `present?` is always false, `presence` always returns `nil`
199
+ sig { returns(NilClass) }
200
+ def presence; end
201
+
202
+ # @shim: since `blank?` is always true, `present?` always returns `false`
203
+ sig { returns(FalseClass) }
204
+ def present?; end
205
+ end
206
+
207
+ class TrueClass
208
+ sig { returns(FalseClass) }
209
+ def blank?; end
210
+
211
+ # @shim: since `present?` is always true, `presence` always returns `self`
212
+ sig { returns(T.self_type) }
213
+ def presence; end
214
+
215
+ # @shim: since `blank?` is always false, `present?` always returns `true`
216
+ sig { returns(TrueClass) }
217
+ def present?; end
218
+ end
219
+
220
+ class Numeric
221
+ sig { returns(FalseClass) }
222
+ def blank?; end
223
+
224
+ # @shim: since `present?` is always true, `presence` always returns `self`
225
+ sig { returns(T.self_type) }
226
+ def presence; end
227
+
228
+ # @shim: since `blank?` is always false, `present?` always returns `true`
229
+ sig { returns(TrueClass) }
230
+ def present?; end
231
+ end
232
+
233
+ class Time
234
+ sig { returns(FalseClass) }
235
+ def blank?; end
236
+
237
+ # @shim: since `present?` is always true, `presence` always returns `self`
238
+ sig { returns(T.self_type) }
239
+ def presence; end
240
+
241
+ # @shim: since `blank?` is always false, `present?` always returns `true`
242
+ sig { returns(TrueClass) }
243
+ def present?; end
244
+ end
245
+
246
+ class Symbol
247
+ # alias for `#start_with?`
248
+ sig { params(string_or_regexp: T.any(String, Regexp)).returns(T::Boolean) }
249
+ def starts_with?(*string_or_regexp); end
250
+
251
+ # alias for `#end_with?`
252
+ sig { params(string_or_regexp: T.any(String, Regexp)).returns(T::Boolean) }
253
+ def ends_with?(*string_or_regexp); end
254
+ end
255
+
256
+ class String
257
+ # alias for `#start_with?`
258
+ sig { params(string_or_regexp: T.any(String, Regexp)).returns(T::Boolean) }
259
+ def starts_with?(*string_or_regexp); end
260
+
261
+ # alias for `#end_with?`
262
+ sig { params(string_or_regexp: T.any(String, Regexp)).returns(T::Boolean) }
263
+ def ends_with?(*string_or_regexp); end
264
+ end