tapioca 0.11.14 → 0.11.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52388d4c8afe40a2b6807e54bf1dd09701cb016ca1fed7ce5d3a691c3f93e0e5
4
- data.tar.gz: 18550aa93626f63257b387154585dc2ae9e74c5aa17c7d4e2b82702bf5ce5b2b
3
+ metadata.gz: 38dec6aff4cfc2907111dda6a6ee1411d5ae7bf58f467a7e8a47094a606f7593
4
+ data.tar.gz: aa5c4ce427eb9e33513ef4b42f69572030c21be2ea12367abc1755fda0c76202
5
5
  SHA512:
6
- metadata.gz: c0be5c5d8108519bbda67d2498ff032273ad855a45c464a5a0acf0780412e7f4d3ee706322ef287fd2882ee0083f3c3fe1ab67611a16a6f45f5aa5a7aeb1a709
7
- data.tar.gz: 6a87ab2319905c976cfb0b6a004c12d613a9200269268c6c452f8f7ba9175a1b7fd29c5d32de945a04614aff1de037463ad3c0fd090f883770a7f72d7f2f1476
6
+ metadata.gz: 1640eb00441de0826936170a8e40010ab5bf3567329ad64e283d8cad4161a37ff16cf02cea1e41eba50816a6f315af8db69be70b65249b61b015532d86c6da05
7
+ data.tar.gz: 410060c7ef464f8fe07b28582cef2a86875fa80ff319051aaea31946cd96ad1e40b07c56165421e99b0d300ea19223a3f20756a520a2cb6bd9c76bf16abca230
@@ -0,0 +1,100 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require "action_text"
6
+ rescue LoadError
7
+ return
8
+ end
9
+
10
+ module Tapioca
11
+ module Dsl
12
+ module Compilers
13
+ # `Tapioca::Dsl::Compilers::ActionText` decorates RBI files for subclasses of
14
+ # `ActiveRecord::Base` that declare [has_rich_text](https://edgeguides.rubyonrails.org/action_text_overview.html#creating-rich-text-content)
15
+ #
16
+ # For example, with the following `ActiveRecord::Base` subclass:
17
+ #
18
+ # ~~~rb
19
+ # class Post < ApplicationRecord
20
+ # has_rich_text :body
21
+ # has_rich_text :title, encrypted: true
22
+ # end
23
+ # ~~~
24
+ #
25
+ # this compiler will produce the RBI file `post.rbi` with the following content:
26
+ #
27
+ # ~~~rbi
28
+ # # typed: strong
29
+ #
30
+ # class Post
31
+ # sig { returns(ActionText::RichText) }
32
+ # def body; end
33
+ #
34
+ # sig { params(value: T.nilable(T.any(ActionText::RichText, String))).returns(T.untyped) }
35
+ # def body=(value); end
36
+ #
37
+ # sig { returns(T::Boolean) }
38
+ # def body?; end
39
+ #
40
+ # sig { returns(ActionText::EncryptedRichText) }
41
+ # def title; end
42
+ #
43
+ # sig { params(value: T.nilable(T.any(ActionText::EncryptedRichText, String))).returns(T.untyped) }
44
+ # def title=(value); end
45
+ #
46
+ # sig { returns(T::Boolean) }
47
+ # def title?; end
48
+ # end
49
+ # ~~~
50
+ class ActionText < Compiler
51
+ extend T::Sig
52
+
53
+ ConstantType = type_member { { fixed: T.class_of(::ActiveRecord::Base) } }
54
+
55
+ sig { override.void }
56
+ def decorate
57
+ root.create_path(constant) do |scope|
58
+ self.class.action_text_associations(constant).each do |name|
59
+ reflection = constant.reflections.fetch(name)
60
+ type = reflection.options.fetch(:class_name)
61
+ name = reflection.name.to_s.sub("rich_text_", "")
62
+ scope.create_method(
63
+ name,
64
+ return_type: type,
65
+ )
66
+ scope.create_method(
67
+ "#{name}?",
68
+ return_type: "T::Boolean",
69
+ )
70
+ scope.create_method(
71
+ "#{name}=",
72
+ parameters: [create_param("value", type: "T.nilable(T.any(#{type}, String))")],
73
+ return_type: "T.untyped",
74
+ )
75
+ end
76
+ end
77
+ end
78
+
79
+ class << self
80
+ extend T::Sig
81
+
82
+ sig { params(constant: T.class_of(::ActiveRecord::Base)).returns(T::Array[String]) }
83
+ def action_text_associations(constant)
84
+ # Implementation copied from https://github.com/rails/rails/blob/31052d0e518b9da103eea2f79d250242ed1e3705/actiontext/lib/action_text/attribute.rb#L66
85
+ constant.reflect_on_all_associations(:has_one)
86
+ .map(&:name).map(&:to_s)
87
+ .select { |n| n.start_with?("rich_text_") }
88
+ end
89
+
90
+ sig { override.returns(T::Enumerable[Module]) }
91
+ def gather_constants
92
+ descendants_of(::ActiveRecord::Base)
93
+ .reject(&:abstract_class?)
94
+ .select { |c| action_text_associations(c).any? }
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -83,6 +83,7 @@ module Tapioca
83
83
  end
84
84
  def perform_later_parameters(parameters, constant_name)
85
85
  if ::Gem::Requirement.new(">= 7.0").satisfied_by?(::ActiveJob.gem_version)
86
+ parameters.reject! { |typed_param| RBI::BlockParam === typed_param.param }
86
87
  parameters + [create_block_param(
87
88
  "block",
88
89
  type: "T.nilable(T.proc.params(job: #{constant_name}).void)",
@@ -72,9 +72,9 @@ module Tapioca
72
72
  def attribute_methods_for_constant
73
73
  patterns = if constant.respond_to?(:attribute_method_patterns)
74
74
  # https://github.com/rails/rails/pull/44367
75
- T.unsafe(constant).attribute_method_patterns
75
+ constant.attribute_method_patterns
76
76
  else
77
- constant.attribute_method_matchers
77
+ T.unsafe(constant).attribute_method_matchers
78
78
  end
79
79
  patterns.flat_map do |pattern|
80
80
  constant.attribute_types.filter_map do |name, value|
@@ -101,8 +101,13 @@ module Tapioca
101
101
  HANDLED_METHOD_TARGETS.include?(target.to_s)
102
102
  end
103
103
 
104
- sig { params(attribute_type_value: ::ActiveModel::Type::Value).returns(::String) }
104
+ sig { params(attribute_type_value: T.untyped).returns(::String) }
105
105
  def type_for(attribute_type_value)
106
+ # This guarantees that the type will remain as T.untyped for attributes in the following form:
107
+ # attribute :name
108
+ # This is because for a generic attribute with no specified type, ActiveModel::Type::Value.new is returned
109
+ return "T.untyped" if attribute_type_value.instance_of?(ActiveModel::Type::Value)
110
+
106
111
  type = case attribute_type_value
107
112
  when ActiveModel::Type::Boolean
108
113
  "T::Boolean"
@@ -119,8 +124,7 @@ module Tapioca
119
124
  when ActiveModel::Type::String
120
125
  "::String"
121
126
  else
122
- # we don't want untyped to be wrapped by T.nilable, so just return early
123
- return "T.untyped"
127
+ attribute_type_value.class.name.to_s
124
128
  end
125
129
 
126
130
  as_nilable_type(type)
@@ -108,6 +108,11 @@ module Tapioca
108
108
  def decorate
109
109
  return unless constant.table_exists?
110
110
 
111
+ # We need to call this to ensure that some attribute aliases are defined, e.g.
112
+ # `id_value` as an alias for `id`.
113
+ # I think this is a regression on Rails 7.1, but we are where we are.
114
+ constant.define_attribute_methods
115
+
111
116
  root.create_path(constant) do |model|
112
117
  model.create_module(AttributeMethodsModuleName) do |mod|
113
118
  (constant.attribute_names + ["id"]).uniq.each do |attribute_name|
@@ -119,9 +124,9 @@ module Tapioca
119
124
  column_name = column_name.to_s
120
125
  patterns = if constant.respond_to?(:attribute_method_patterns)
121
126
  # https://github.com/rails/rails/pull/44367
122
- T.unsafe(constant).attribute_method_patterns
127
+ constant.attribute_method_patterns
123
128
  else
124
- constant.attribute_method_matchers
129
+ T.unsafe(constant).attribute_method_matchers
125
130
  end
126
131
  new_method_names = patterns.map { |m| m.method_name(attribute_name) }
127
132
  old_method_names = patterns.map { |m| m.method_name(column_name) }
@@ -110,11 +110,10 @@ module Tapioca
110
110
  return_type: "ActiveSupport::StringInquirer",
111
111
  )
112
112
 
113
- return_type = sorbet_supports?(:generic_class) ? "T::Class[T.anything]" : "Class"
114
113
  mod.create_method(
115
114
  "#{role}_class",
116
115
  parameters: [],
117
- return_type: return_type,
116
+ return_type: "T::Class[T.anything]",
118
117
  )
119
118
 
120
119
  mod.create_method(
@@ -55,7 +55,10 @@ module Tapioca
55
55
  root.create_path(constant) do |input_object|
56
56
  arguments.each do |argument|
57
57
  name = argument.keyword.to_s
58
- input_object.create_method(name, return_type: Helpers::GraphqlTypeHelper.type_for(argument, constant))
58
+ input_object.create_method(
59
+ name,
60
+ return_type: Helpers::GraphqlTypeHelper.type_for_argument(argument, constant),
61
+ )
59
62
  end
60
63
  end
61
64
  end
@@ -76,7 +76,7 @@ module Tapioca
76
76
  def argument_type(argument, constant)
77
77
  return "T.untyped" unless argument
78
78
 
79
- Helpers::GraphqlTypeHelper.type_for(argument, constant)
79
+ Helpers::GraphqlTypeHelper.type_for_argument(argument, constant)
80
80
  end
81
81
 
82
82
  class << self
@@ -85,6 +85,9 @@ module Tapioca
85
85
  "::String"
86
86
  when ActiveRecord::Type::Serialized
87
87
  serialized_column_type(column_type)
88
+ when defined?(ActiveRecord::Normalization::NormalizedValueType) &&
89
+ ActiveRecord::Normalization::NormalizedValueType
90
+ type_for_activerecord_value(column_type.cast_type)
88
91
  when defined?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Uuid) &&
89
92
  ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Uuid
90
93
  "::String"
@@ -15,7 +15,7 @@ module Tapioca
15
15
  constant: T.any(T.class_of(GraphQL::Schema::Mutation), T.class_of(GraphQL::Schema::InputObject)),
16
16
  ).returns(String)
17
17
  end
18
- def type_for(argument, constant)
18
+ def type_for_argument(argument, constant)
19
19
  type = if argument.loads
20
20
  loads_type = ::GraphQL::Schema::Wrapper.new(argument.loads)
21
21
  loads_type = loads_type.to_list_type if argument.type.list?
@@ -25,6 +25,36 @@ module Tapioca
25
25
  argument.type
26
26
  end
27
27
 
28
+ prepare = argument.prepare
29
+ prepare_method = if prepare
30
+ if constant.respond_to?(prepare)
31
+ constant.method(prepare)
32
+ end
33
+ end
34
+
35
+ type_for(
36
+ type,
37
+ ignore_nilable_wrapper: has_replaceable_default?(argument),
38
+ prepare_method: prepare_method,
39
+ )
40
+ end
41
+
42
+ sig do
43
+ params(
44
+ type: T.any(
45
+ GraphQL::Schema::Wrapper,
46
+ T.class_of(GraphQL::Schema::Scalar),
47
+ T.class_of(GraphQL::Schema::Enum),
48
+ T.class_of(GraphQL::Schema::Union),
49
+ T.class_of(GraphQL::Schema::Object),
50
+ T.class_of(GraphQL::Schema::Interface),
51
+ T.class_of(GraphQL::Schema::InputObject),
52
+ ),
53
+ ignore_nilable_wrapper: T::Boolean,
54
+ prepare_method: T.nilable(Method),
55
+ ).returns(String)
56
+ end
57
+ def type_for(type, ignore_nilable_wrapper: false, prepare_method: nil)
28
58
  unwrapped_type = type.unwrap
29
59
 
30
60
  parsed_type = case unwrapped_type
@@ -65,14 +95,11 @@ module Tapioca
65
95
  "T.untyped"
66
96
  end
67
97
 
68
- if argument.prepare.is_a?(Symbol) || argument.prepare.is_a?(String)
69
- if constant.respond_to?(argument.prepare)
70
- prepare_method = constant.method(argument.prepare)
71
- prepare_signature = Runtime::Reflection.signature_of(prepare_method)
72
-
73
- if valid_return_type?(prepare_signature&.return_type)
74
- parsed_type = prepare_signature.return_type&.to_s
75
- end
98
+ if prepare_method
99
+ prepare_signature = Runtime::Reflection.signature_of(prepare_method)
100
+ prepare_return_type = prepare_signature&.return_type
101
+ if valid_return_type?(prepare_return_type)
102
+ parsed_type = prepare_return_type&.to_s
76
103
  end
77
104
  end
78
105
 
@@ -80,7 +107,7 @@ module Tapioca
80
107
  parsed_type = "T::Array[#{parsed_type}]"
81
108
  end
82
109
 
83
- unless type.non_null? || has_replaceable_default?(argument)
110
+ unless type.non_null? || ignore_nilable_wrapper
84
111
  parsed_type = RBIHelper.as_nilable_type(parsed_type)
85
112
  end
86
113
 
@@ -271,9 +271,7 @@ module Tapioca
271
271
 
272
272
  klass = class_of(value)
273
273
 
274
- klass_name = if klass == ObjectSpace::WeakMap
275
- sorbet_supports?(:non_generic_weak_map) ? "ObjectSpace::WeakMap" : "ObjectSpace::WeakMap[T.untyped]"
276
- elsif T::Generic === klass
274
+ klass_name = if T::Generic === klass
277
275
  generic_name_of(klass)
278
276
  else
279
277
  name_of(klass)
@@ -24,8 +24,6 @@ module Tapioca
24
24
  FEATURE_REQUIREMENTS = T.let(
25
25
  {
26
26
  # feature_name: ::Gem::Requirement.new(">= ___"), # https://github.com/sorbet/sorbet/pull/___
27
- non_generic_weak_map: ::Gem::Requirement.new(">= 0.5.10587"), # https://github.com/sorbet/sorbet/pull/6610
28
- generic_class: ::Gem::Requirement.new(">= 0.5.10820"), # https://github.com/sorbet/sorbet/pull/6781
29
27
  }.freeze,
30
28
  T::Hash[Symbol, ::Gem::Requirement],
31
29
  )
@@ -32,7 +32,6 @@ require "tapioca/helpers/git_attributes"
32
32
  require "tapioca/helpers/sorbet_helper"
33
33
  require "tapioca/helpers/rbi_helper"
34
34
  require "tapioca/sorbet_ext/backcompat_patches"
35
- require "tapioca/sorbet_ext/fixed_hash_patch"
36
35
  require "tapioca/sorbet_ext/name_patch"
37
36
  require "tapioca/sorbet_ext/generic_name_patch"
38
37
  require "tapioca/sorbet_ext/proc_bind_patch"
@@ -1,24 +1,6 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- unless defined?(T.anything)
5
- module T
6
- class << self
7
- def anything
8
- T.untyped
9
- end
10
- end
11
- end
12
- end
4
+ # This file contains patches to make Tapioca work with older versions of Sorbet.
13
5
 
14
- unless defined?(T::Class)
15
- module T
16
- module Class
17
- class << self
18
- def [](type)
19
- T.untyped
20
- end
21
- end
22
- end
23
- end
24
- end
6
+ # NOTE: If there is currently no need for any patches, this file will be empty.
@@ -18,32 +18,26 @@ module T
18
18
  Tapioca::Runtime::GenericTypeRegistry.register_type(constant, types)
19
19
  end
20
20
 
21
- def type_member(variance = :invariant, fixed: nil, lower: nil, upper: nil, &bounds_proc)
21
+ def type_member(variance = :invariant, &bounds_proc)
22
22
  # `T::Generic#type_member` just instantiates a `T::Type::TypeMember` instance and returns it.
23
23
  # We use that when registering the type member and then later return it from this method.
24
24
  Tapioca::TypeVariableModule.new(
25
25
  T.cast(self, Module),
26
26
  Tapioca::TypeVariableModule::Type::Member,
27
27
  variance,
28
- fixed,
29
- lower,
30
- upper,
31
28
  bounds_proc,
32
29
  ).tap do |type_variable|
33
30
  Tapioca::Runtime::GenericTypeRegistry.register_type_variable(self, type_variable)
34
31
  end
35
32
  end
36
33
 
37
- def type_template(variance = :invariant, fixed: nil, lower: nil, upper: nil, &bounds_proc)
34
+ def type_template(variance = :invariant, &bounds_proc)
38
35
  # `T::Generic#type_template` just instantiates a `T::Type::TypeTemplate` instance and returns it.
39
36
  # We use that when registering the type template and then later return it from this method.
40
37
  Tapioca::TypeVariableModule.new(
41
38
  T.cast(self, Module),
42
39
  Tapioca::TypeVariableModule::Type::Template,
43
40
  variance,
44
- fixed,
45
- lower,
46
- upper,
47
41
  bounds_proc,
48
42
  ).tap do |type_variable|
49
43
  Tapioca::Runtime::GenericTypeRegistry.register_type_variable(self, type_variable)
@@ -57,9 +51,6 @@ module T
57
51
  T.cast(self, Module),
58
52
  Tapioca::TypeVariableModule::Type::HasAttachedClass,
59
53
  variance,
60
- nil,
61
- nil,
62
- nil,
63
54
  bounds_proc,
64
55
  ),
65
56
  )
@@ -93,29 +84,9 @@ module T
93
84
  end
94
85
 
95
86
  module Utils
96
- # This duplication is required to preserve backwards compatibility with sorbet-runtime versions prior to the
97
- # introduction of the `Private` module in https://github.com/sorbet/sorbet/pull/6559.
98
- if defined?(T::Utils::Private)
99
- module Private
100
- module PrivateCoercePatch
101
- def coerce_and_check_module_types(val, check_val, check_module_type)
102
- if val.is_a?(Tapioca::TypeVariableModule)
103
- val.coerce_to_type_variable
104
- elsif val.respond_to?(:__tapioca_override_type)
105
- val.__tapioca_override_type
106
- else
107
- super
108
- end
109
- end
110
- end
111
-
112
- class << self
113
- prepend(PrivateCoercePatch)
114
- end
115
- end
116
- else
117
- module CoercePatch
118
- def coerce(val)
87
+ module Private
88
+ module PrivateCoercePatch
89
+ def coerce_and_check_module_types(val, check_val, check_module_type)
119
90
  if val.is_a?(Tapioca::TypeVariableModule)
120
91
  val.coerce_to_type_variable
121
92
  elsif val.respond_to?(:__tapioca_override_type)
@@ -127,7 +98,7 @@ module T
127
98
  end
128
99
 
129
100
  class << self
130
- prepend(CoercePatch)
101
+ prepend(PrivateCoercePatch)
131
102
  end
132
103
  end
133
104
  end
@@ -159,35 +130,27 @@ module Tapioca
159
130
  end
160
131
  end
161
132
 
133
+ DEFAULT_BOUNDS_PROC = T.let(-> { {} }, T.proc.returns(T::Hash[Symbol, T.untyped]))
134
+
162
135
  sig { returns(Type) }
163
136
  attr_reader :type
164
137
 
165
- # rubocop:disable Metrics/ParameterLists
166
138
  sig do
167
139
  params(
168
140
  context: Module,
169
141
  type: Type,
170
142
  variance: Symbol,
171
- fixed: T.untyped,
172
- lower: T.untyped,
173
- upper: T.untyped,
174
143
  bounds_proc: T.nilable(T.proc.returns(T::Hash[Symbol, T.untyped])),
175
144
  ).void
176
145
  end
177
- def initialize(context, type, variance, fixed, lower, upper, bounds_proc)
146
+ def initialize(context, type, variance, bounds_proc)
178
147
  @context = context
179
148
  @type = type
180
149
  @variance = variance
181
- @bounds_proc = if bounds_proc
182
- bounds_proc
183
- else
184
- build_bounds_proc(fixed, lower, upper)
185
- end
150
+ @bounds_proc = bounds_proc || DEFAULT_BOUNDS_PROC
186
151
 
187
152
  super()
188
153
  end
189
- # rubocop:enable Metrics/ParameterLists
190
-
191
154
  sig { returns(T.nilable(String)) }
192
155
  def name
193
156
  constant_name = super
@@ -221,19 +184,6 @@ module Tapioca
221
184
 
222
185
  private
223
186
 
224
- sig do
225
- params(fixed: T.untyped, lower: T.untyped, upper: T.untyped)
226
- .returns(T.proc.returns(T::Hash[Symbol, T.untyped]))
227
- end
228
- def build_bounds_proc(fixed, lower, upper)
229
- bounds = {}
230
- bounds[:fixed] = fixed unless fixed.nil?
231
- bounds[:lower] = lower unless lower.nil?
232
- bounds[:upper] = upper unless upper.nil?
233
-
234
- -> { bounds }
235
- end
236
-
237
187
  sig { returns(T::Hash[Symbol, T.untyped]) }
238
188
  def bounds
239
189
  @bounds ||= @bounds_proc.call
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.11.14"
5
+ VERSION = "0.11.16"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapioca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.14
4
+ version: 0.11.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2023-12-18 00:00:00.000000000 Z
14
+ date: 2024-01-12 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -81,14 +81,14 @@ dependencies:
81
81
  requirements:
82
82
  - - ">="
83
83
  - !ruby/object:Gem::Version
84
- version: 0.5.10187
84
+ version: 0.5.10820
85
85
  type: :runtime
86
86
  prerelease: false
87
87
  version_requirements: !ruby/object:Gem::Requirement
88
88
  requirements:
89
89
  - - ">="
90
90
  - !ruby/object:Gem::Version
91
- version: 0.5.10187
91
+ version: 0.5.10820
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: spoom
94
94
  requirement: !ruby/object:Gem::Requirement
@@ -173,6 +173,7 @@ files:
173
173
  - lib/tapioca/dsl/compilers/aasm.rb
174
174
  - lib/tapioca/dsl/compilers/action_controller_helpers.rb
175
175
  - lib/tapioca/dsl/compilers/action_mailer.rb
176
+ - lib/tapioca/dsl/compilers/action_text.rb
176
177
  - lib/tapioca/dsl/compilers/active_job.rb
177
178
  - lib/tapioca/dsl/compilers/active_model_attributes.rb
178
179
  - lib/tapioca/dsl/compilers/active_model_secure_password.rb
@@ -265,7 +266,6 @@ files:
265
266
  - lib/tapioca/runtime/trackers/required_ancestor.rb
266
267
  - lib/tapioca/runtime/trackers/tracker.rb
267
268
  - lib/tapioca/sorbet_ext/backcompat_patches.rb
268
- - lib/tapioca/sorbet_ext/fixed_hash_patch.rb
269
269
  - lib/tapioca/sorbet_ext/generic_name_patch.rb
270
270
  - lib/tapioca/sorbet_ext/name_patch.rb
271
271
  - lib/tapioca/sorbet_ext/proc_bind_patch.rb
@@ -293,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
293
293
  - !ruby/object:Gem::Version
294
294
  version: '0'
295
295
  requirements: []
296
- rubygems_version: 3.4.22
296
+ rubygems_version: 3.5.4
297
297
  signing_key:
298
298
  specification_version: 4
299
299
  summary: A Ruby Interface file generator for gems, core types and the Ruby standard
@@ -1,20 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- module T
5
- module Types
6
- class FixedHash
7
- def name
8
- entries = @types.map do |(k, v)|
9
- if Symbol === k && ":#{k}" == k.inspect
10
- "#{k}: #{v}"
11
- else
12
- "#{k.inspect} => #{v}"
13
- end
14
- end
15
-
16
- "{#{entries.join(", ")}}"
17
- end
18
- end
19
- end
20
- end