tapioca 0.8.3 → 0.9.2

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/Gemfile +5 -2
  3. data/README.md +188 -36
  4. data/lib/tapioca/cli.rb +130 -66
  5. data/lib/tapioca/commands/annotations.rb +167 -34
  6. data/lib/tapioca/commands/check_shims.rb +101 -0
  7. data/lib/tapioca/commands/{init.rb → configure.rb} +1 -1
  8. data/lib/tapioca/commands/dsl.rb +1 -1
  9. data/lib/tapioca/commands/gem.rb +15 -10
  10. data/lib/tapioca/commands.rb +2 -1
  11. data/lib/tapioca/dsl/compiler.rb +1 -13
  12. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +1 -1
  13. data/lib/tapioca/dsl/compilers/active_record_relations.rb +17 -0
  14. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +5 -4
  15. data/lib/tapioca/dsl/compilers/frozen_record.rb +2 -2
  16. data/lib/tapioca/dsl/compilers/protobuf.rb +6 -0
  17. data/lib/tapioca/dsl/compilers.rb +0 -4
  18. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +21 -3
  19. data/lib/tapioca/dsl/pipeline.rb +0 -2
  20. data/lib/tapioca/dsl.rb +8 -0
  21. data/lib/tapioca/executor.rb +0 -3
  22. data/lib/tapioca/gem/events.rb +22 -3
  23. data/lib/tapioca/gem/listeners/base.rb +11 -0
  24. data/lib/tapioca/gem/listeners/dynamic_mixins.rb +5 -0
  25. data/lib/tapioca/gem/listeners/foreign_constants.rb +65 -0
  26. data/lib/tapioca/gem/listeners/methods.rb +7 -18
  27. data/lib/tapioca/gem/listeners/mixins.rb +31 -10
  28. data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +5 -0
  29. data/lib/tapioca/gem/listeners/sorbet_enums.rb +5 -0
  30. data/lib/tapioca/gem/listeners/sorbet_helpers.rb +5 -0
  31. data/lib/tapioca/gem/listeners/sorbet_props.rb +5 -0
  32. data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +5 -0
  33. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +6 -1
  34. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +5 -0
  35. data/lib/tapioca/gem/listeners/source_location.rb +67 -0
  36. data/lib/tapioca/gem/listeners/subconstants.rb +5 -0
  37. data/lib/tapioca/gem/listeners/yard_doc.rb +5 -0
  38. data/lib/tapioca/gem/listeners.rb +2 -0
  39. data/lib/tapioca/gem/pipeline.rb +64 -19
  40. data/lib/tapioca/gem.rb +6 -0
  41. data/lib/tapioca/gemfile.rb +7 -6
  42. data/lib/tapioca/helpers/cli_helper.rb +8 -2
  43. data/lib/tapioca/helpers/config_helper.rb +0 -2
  44. data/lib/tapioca/helpers/env_helper.rb +16 -0
  45. data/lib/tapioca/helpers/rbi_files_helper.rb +255 -0
  46. data/lib/tapioca/helpers/rbi_helper.rb +98 -94
  47. data/lib/tapioca/helpers/sorbet_helper.rb +2 -3
  48. data/lib/tapioca/helpers/test/content.rb +0 -2
  49. data/lib/tapioca/helpers/test/template.rb +0 -2
  50. data/lib/tapioca/internal.rb +36 -12
  51. data/lib/tapioca/rbi_ext/model.rb +2 -15
  52. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +18 -16
  53. data/lib/tapioca/runtime/reflection.rb +26 -0
  54. data/lib/tapioca/runtime/trackers/constant_definition.rb +44 -16
  55. data/lib/tapioca/runtime/trackers/mixin.rb +49 -14
  56. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +1 -4
  57. data/lib/tapioca/sorbet_ext/name_patch.rb +15 -5
  58. data/lib/tapioca/sorbet_ext/proc_bind_patch.rb +40 -0
  59. data/lib/tapioca/static/requires_compiler.rb +0 -2
  60. data/lib/tapioca/static/symbol_loader.rb +26 -30
  61. data/lib/tapioca/static/symbol_table_parser.rb +0 -3
  62. data/lib/tapioca/version.rb +1 -1
  63. data/lib/tapioca.rb +3 -0
  64. metadata +24 -7
  65. data/lib/tapioca/dsl/helpers/param_helper.rb +0 -55
  66. data/lib/tapioca/helpers/shims_helper.rb +0 -115
  67. data/lib/tapioca/helpers/signatures_helper.rb +0 -17
  68. data/lib/tapioca/helpers/type_variable_helper.rb +0 -43
@@ -1,18 +1,28 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- # We need sorbet to compile the signature for `qualified_name_of` before applying
5
- # the patch to avoid an infinite loop.
6
- T::Utils.signature_for_method(::Tapioca::Runtime::Reflection.method(:qualified_name_of))
7
-
8
4
  module T
9
5
  module Types
10
6
  class Simple
11
7
  module NamePatch
8
+ NAME_METHOD = T.let(Module.instance_method(:name), UnboundMethod)
9
+
12
10
  def name
13
11
  # Sorbet memoizes this method into the `@name` instance variable but
14
12
  # doing so means that types get memoized before this patch is applied
15
- ::Tapioca::Runtime::Reflection.qualified_name_of(@raw_type)
13
+ qualified_name_of(@raw_type)
14
+ end
15
+
16
+ def qualified_name_of(constant)
17
+ name = NAME_METHOD.bind_call(constant)
18
+ name = nil if name&.start_with?("#<")
19
+ return if name.nil?
20
+
21
+ if name.start_with?("::")
22
+ name
23
+ else
24
+ "::#{name}"
25
+ end
16
26
  end
17
27
  end
18
28
 
@@ -0,0 +1,40 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module T
5
+ module Types
6
+ module ProcBindPatch
7
+ def initialize(arg_types, returns, bind = T::Private::Methods::ARG_NOT_PROVIDED)
8
+ super(arg_types, returns)
9
+
10
+ unless bind == T::Private::Methods::ARG_NOT_PROVIDED
11
+ @bind = T.let(T::Utils.coerce(bind), T::Types::Base)
12
+ end
13
+ end
14
+
15
+ def name
16
+ name = super
17
+ name = name.sub("T.proc", "T.proc.bind(#{@bind})") unless @bind.nil?
18
+ name
19
+ end
20
+ end
21
+
22
+ Proc.prepend(ProcBindPatch)
23
+ end
24
+ end
25
+
26
+ module T
27
+ module Private
28
+ module Methods
29
+ module ProcBindPatch
30
+ def finalize_proc(decl)
31
+ super
32
+
33
+ T.unsafe(T::Types::Proc).new(decl.params, decl.returns, decl.bind)
34
+ end
35
+ end
36
+
37
+ singleton_class.prepend(ProcBindPatch)
38
+ end
39
+ end
40
+ end
@@ -1,8 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "spoom"
5
-
6
4
  module Tapioca
7
5
  module Static
8
6
  class RequiresCompiler
@@ -1,9 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "json"
5
- require "tempfile"
6
-
7
4
  module Tapioca
8
5
  module Static
9
6
  module SymbolLoader
@@ -22,12 +19,21 @@ module Tapioca
22
19
  T.must(@payload_symbols)
23
20
  end
24
21
 
25
- sig { returns(T::Set[String]) }
26
- def engine_symbols
27
- unless @engine_symbols
28
- @engine_symbols = T.let(load_engine_symbols, T.nilable(T::Set[String]))
22
+ sig { params(gem: Gemfile::GemSpec).returns(T::Set[String]) }
23
+ def engine_symbols(gem)
24
+ gem_engine = engines.find do |engine|
25
+ gem.contains_path?(engine.config.root.to_s)
26
+ end
27
+
28
+ return Set.new unless gem_engine
29
+
30
+ paths = gem_engine.config.eager_load_paths.flat_map do |load_path|
31
+ Pathname.glob("#{load_path}/**/*.rb")
29
32
  end
30
- T.must(@engine_symbols)
33
+
34
+ symbols_from_paths(paths)
35
+ rescue
36
+ Set.new
31
37
  end
32
38
 
33
39
  sig { params(gem: Gemfile::GemSpec).returns(T::Set[String]) }
@@ -37,31 +43,21 @@ module Tapioca
37
43
 
38
44
  private
39
45
 
40
- sig { params(input: String, table_type: String).returns(String) }
41
- def symbol_table_json_from(input, table_type: "symbol-table-json")
42
- sorbet("--no-config", "--quiet", "--print=#{table_type}", input).out
43
- end
44
-
45
- sig { returns(T::Set[String]) }
46
- def load_engine_symbols
47
- return Set.new unless Object.const_defined?("Rails::Engine")
48
-
49
- engine = descendants_of(Object.const_get("Rails::Engine"))
50
- .reject(&:abstract_railtie?)
51
- .find do |klass|
52
- name = name_of(klass)
53
- !name.nil? && payload_symbols.include?(name)
54
- end
46
+ sig { returns(T::Array[T.class_of(Rails::Engine)]) }
47
+ def engines
48
+ @engines = T.let(@engines, T.nilable(T::Array[T.class_of(Rails::Engine)]))
55
49
 
56
- return Set.new unless engine
57
-
58
- paths = engine.config.eager_load_paths.flat_map do |load_path|
59
- Pathname.glob("#{load_path}/**/*.rb")
50
+ @engines ||= if Object.const_defined?("Rails::Engine")
51
+ descendants_of(Object.const_get("Rails::Engine"))
52
+ .reject(&:abstract_railtie?)
53
+ else
54
+ []
60
55
  end
56
+ end
61
57
 
62
- symbols_from_paths(paths)
63
- rescue
64
- Set.new
58
+ sig { params(input: String, table_type: String).returns(String) }
59
+ def symbol_table_json_from(input, table_type: "symbol-table-json")
60
+ sorbet("--no-config", "--quiet", "--print=#{table_type}", input).out
65
61
  end
66
62
 
67
63
  sig { params(paths: T::Array[Pathname]).returns(T::Set[String]) }
@@ -1,9 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "json"
5
- require "tempfile"
6
-
7
4
  module Tapioca
8
5
  module Static
9
6
  class SymbolTableParser
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.8.3"
5
+ VERSION = "0.9.2"
6
6
  end
data/lib/tapioca.rb CHANGED
@@ -43,6 +43,9 @@ module Tapioca
43
43
  "activesupport" => "false",
44
44
  }.freeze, T::Hash[String, String])
45
45
 
46
+ DEFAULT_RBI_MAX_LINE_LENGTH = 120
47
+ DEFAULT_ENVIRONMENT = "development"
48
+
46
49
  CENTRAL_REPO_ROOT_URI = "https://raw.githubusercontent.com/Shopify/rbi-central/main"
47
50
  CENTRAL_REPO_INDEX_PATH = "index.json"
48
51
  CENTRAL_REPO_ANNOTATIONS_DIR = "rbi/annotations"
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.8.3
4
+ version: 0.9.2
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: 2022-06-28 00:00:00.000000000 Z
14
+ date: 2022-07-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -27,6 +27,20 @@ dependencies:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
29
  version: 1.17.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: netrc
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 0.11.0
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.11.0
30
44
  - !ruby/object:Gem::Dependency
31
45
  name: parallel
32
46
  requirement: !ruby/object:Gem::Requirement
@@ -153,10 +167,11 @@ files:
153
167
  - lib/tapioca/cli.rb
154
168
  - lib/tapioca/commands.rb
155
169
  - lib/tapioca/commands/annotations.rb
170
+ - lib/tapioca/commands/check_shims.rb
156
171
  - lib/tapioca/commands/command.rb
172
+ - lib/tapioca/commands/configure.rb
157
173
  - lib/tapioca/commands/dsl.rb
158
174
  - lib/tapioca/commands/gem.rb
159
- - lib/tapioca/commands/init.rb
160
175
  - lib/tapioca/commands/require.rb
161
176
  - lib/tapioca/commands/todo.rb
162
177
  - lib/tapioca/dsl.rb
@@ -192,13 +207,14 @@ files:
192
207
  - lib/tapioca/dsl/extensions/frozen_record.rb
193
208
  - lib/tapioca/dsl/helpers/active_record_column_type_helper.rb
194
209
  - lib/tapioca/dsl/helpers/active_record_constants_helper.rb
195
- - lib/tapioca/dsl/helpers/param_helper.rb
196
210
  - lib/tapioca/dsl/pipeline.rb
197
211
  - lib/tapioca/executor.rb
212
+ - lib/tapioca/gem.rb
198
213
  - lib/tapioca/gem/events.rb
199
214
  - lib/tapioca/gem/listeners.rb
200
215
  - lib/tapioca/gem/listeners/base.rb
201
216
  - lib/tapioca/gem/listeners/dynamic_mixins.rb
217
+ - lib/tapioca/gem/listeners/foreign_constants.rb
202
218
  - lib/tapioca/gem/listeners/methods.rb
203
219
  - lib/tapioca/gem/listeners/mixins.rb
204
220
  - lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb
@@ -208,22 +224,22 @@ files:
208
224
  - lib/tapioca/gem/listeners/sorbet_required_ancestors.rb
209
225
  - lib/tapioca/gem/listeners/sorbet_signatures.rb
210
226
  - lib/tapioca/gem/listeners/sorbet_type_variables.rb
227
+ - lib/tapioca/gem/listeners/source_location.rb
211
228
  - lib/tapioca/gem/listeners/subconstants.rb
212
229
  - lib/tapioca/gem/listeners/yard_doc.rb
213
230
  - lib/tapioca/gem/pipeline.rb
214
231
  - lib/tapioca/gemfile.rb
215
232
  - lib/tapioca/helpers/cli_helper.rb
216
233
  - lib/tapioca/helpers/config_helper.rb
234
+ - lib/tapioca/helpers/env_helper.rb
217
235
  - lib/tapioca/helpers/gem_helper.rb
236
+ - lib/tapioca/helpers/rbi_files_helper.rb
218
237
  - lib/tapioca/helpers/rbi_helper.rb
219
- - lib/tapioca/helpers/shims_helper.rb
220
- - lib/tapioca/helpers/signatures_helper.rb
221
238
  - lib/tapioca/helpers/sorbet_helper.rb
222
239
  - lib/tapioca/helpers/test/content.rb
223
240
  - lib/tapioca/helpers/test/dsl_compiler.rb
224
241
  - lib/tapioca/helpers/test/isolation.rb
225
242
  - lib/tapioca/helpers/test/template.rb
226
- - lib/tapioca/helpers/type_variable_helper.rb
227
243
  - lib/tapioca/internal.rb
228
244
  - lib/tapioca/rbi_ext/model.rb
229
245
  - lib/tapioca/rbi_formatter.rb
@@ -240,6 +256,7 @@ files:
240
256
  - lib/tapioca/sorbet_ext/fixed_hash_patch.rb
241
257
  - lib/tapioca/sorbet_ext/generic_name_patch.rb
242
258
  - lib/tapioca/sorbet_ext/name_patch.rb
259
+ - lib/tapioca/sorbet_ext/proc_bind_patch.rb
243
260
  - lib/tapioca/static/requires_compiler.rb
244
261
  - lib/tapioca/static/symbol_loader.rb
245
262
  - lib/tapioca/static/symbol_table_parser.rb
@@ -1,55 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "tapioca/helpers/signatures_helper"
5
-
6
- module Tapioca
7
- module Dsl
8
- module Helpers
9
- module ParamHelper
10
- extend T::Sig
11
- include SignaturesHelper
12
-
13
- sig { params(name: String, type: String).returns(RBI::TypedParam) }
14
- def create_param(name, type:)
15
- create_typed_param(RBI::Param.new(name), type)
16
- end
17
-
18
- sig { params(name: String, type: String, default: String).returns(RBI::TypedParam) }
19
- def create_opt_param(name, type:, default:)
20
- create_typed_param(RBI::OptParam.new(name, default), type)
21
- end
22
-
23
- sig { params(name: String, type: String).returns(RBI::TypedParam) }
24
- def create_rest_param(name, type:)
25
- create_typed_param(RBI::RestParam.new(name), type)
26
- end
27
-
28
- sig { params(name: String, type: String).returns(RBI::TypedParam) }
29
- def create_kw_param(name, type:)
30
- create_typed_param(RBI::KwParam.new(name), type)
31
- end
32
-
33
- sig { params(name: String, type: String, default: String).returns(RBI::TypedParam) }
34
- def create_kw_opt_param(name, type:, default:)
35
- create_typed_param(RBI::KwOptParam.new(name, default), type)
36
- end
37
-
38
- sig { params(name: String, type: String).returns(RBI::TypedParam) }
39
- def create_kw_rest_param(name, type:)
40
- create_typed_param(RBI::KwRestParam.new(name), type)
41
- end
42
-
43
- sig { params(name: String, type: String).returns(RBI::TypedParam) }
44
- def create_block_param(name, type:)
45
- create_typed_param(RBI::BlockParam.new(name), type)
46
- end
47
-
48
- sig { params(param: RBI::Param, type: String).returns(RBI::TypedParam) }
49
- def create_typed_param(param, type)
50
- RBI::TypedParam.new(param: param, type: sanitize_signature_types(type))
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,115 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module ShimsHelper
6
- extend T::Sig
7
- extend T::Helpers
8
-
9
- requires_ancestor { Thor::Shell }
10
-
11
- SORBET_PAYLOAD_URL = "https://github.com/sorbet/sorbet/tree/master/rbi"
12
-
13
- sig { params(index: RBI::Index, dir: String).void }
14
- def index_payload(index, dir)
15
- return unless Dir.exist?(dir)
16
-
17
- say("Loading Sorbet payload... ")
18
- files = Dir.glob("#{dir}/**/*.rbi").sort
19
- parse_and_index_files(index, files)
20
- say(" Done", :green)
21
- end
22
-
23
- sig { params(index: RBI::Index, kind: String, dir: String).void }
24
- def index_rbis(index, kind, dir)
25
- return unless Dir.exist?(dir) && !Dir.empty?(dir)
26
-
27
- say("Loading #{kind} RBIs from #{dir}... ")
28
- files = Dir.glob("#{dir}/**/*.rbi").sort
29
- parse_and_index_files(index, files)
30
- say(" Done", :green)
31
- end
32
-
33
- sig { params(index: RBI::Index, shim_rbi_dir: String).returns(T::Hash[String, T::Array[RBI::Node]]) }
34
- def duplicated_nodes_from_index(index, shim_rbi_dir)
35
- duplicates = {}
36
- say("Looking for duplicates... ")
37
- index.keys.each do |key|
38
- nodes = index[key]
39
- next unless shims_have_duplicates?(nodes, shim_rbi_dir)
40
-
41
- duplicates[key] = nodes
42
- end
43
- say(" Done", :green)
44
- duplicates
45
- end
46
-
47
- sig { params(loc: RBI::Loc, path_prefix: T.nilable(String)).returns(String) }
48
- def location_to_payload_url(loc, path_prefix:)
49
- return loc.to_s unless path_prefix
50
-
51
- url = loc.file || ""
52
- return loc.to_s unless url.start_with?(path_prefix)
53
-
54
- url = url.sub(path_prefix, SORBET_PAYLOAD_URL)
55
- url = "#{url}#L#{loc.begin_line}"
56
- url
57
- end
58
-
59
- private
60
-
61
- sig { params(index: RBI::Index, files: T::Array[String]).void }
62
- def parse_and_index_files(index, files)
63
- trees = files.map do |file|
64
- RBI::Parser.parse_file(file)
65
- rescue RBI::ParseError => e
66
- say_error("\nWarning: #{e} (#{e.location})", :yellow)
67
- end.compact
68
- index.visit_all(trees)
69
- end
70
-
71
- sig { params(nodes: T::Array[RBI::Node], shim_rbi_dir: String).returns(T::Boolean) }
72
- def shims_have_duplicates?(nodes, shim_rbi_dir)
73
- return false if nodes.size == 1
74
-
75
- shims = extract_shims(nodes, shim_rbi_dir)
76
- return false if shims.empty?
77
-
78
- props = extract_methods_and_attrs(shims)
79
- return false if props.empty?
80
-
81
- shims_with_sigs = extract_nodes_with_sigs(props)
82
- shims_with_sigs.each do |shim|
83
- shim_sigs = shim.sigs
84
-
85
- extract_methods_and_attrs(nodes).each do |node|
86
- next if node == shim
87
- return true if shim_sigs.all? { |sig| node.sigs.include?(sig) }
88
- end
89
-
90
- return false
91
- end
92
-
93
- true
94
- end
95
-
96
- sig { params(nodes: T::Array[RBI::Node], shim_rbi_dir: String).returns(T::Array[RBI::Node]) }
97
- def extract_shims(nodes, shim_rbi_dir)
98
- nodes.select do |node|
99
- node.loc&.file&.start_with?(shim_rbi_dir)
100
- end
101
- end
102
-
103
- sig { params(nodes: T::Array[RBI::Node]).returns(T::Array[T.any(RBI::Method, RBI::Attr)]) }
104
- def extract_methods_and_attrs(nodes)
105
- T.cast(nodes.select do |node|
106
- node.is_a?(RBI::Method) || node.is_a?(RBI::Attr)
107
- end, T::Array[T.any(RBI::Method, RBI::Attr)])
108
- end
109
-
110
- sig { params(nodes: T::Array[T.any(RBI::Method, RBI::Attr)]).returns(T::Array[T.any(RBI::Method, RBI::Attr)]) }
111
- def extract_nodes_with_sigs(nodes)
112
- nodes.reject { |node| node.sigs.empty? }
113
- end
114
- end
115
- end
@@ -1,17 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module SignaturesHelper
6
- extend T::Sig
7
-
8
- sig { params(sig_string: String).returns(String) }
9
- def sanitize_signature_types(sig_string)
10
- sig_string
11
- .gsub(".returns(<VOID>)", ".void")
12
- .gsub("<VOID>", "void")
13
- .gsub("<NOT-TYPED>", "T.untyped")
14
- .gsub(".params()", "")
15
- end
16
- end
17
- end
@@ -1,43 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module TypeVariableHelper
6
- extend T::Sig
7
- extend SorbetHelper
8
-
9
- sig do
10
- params(
11
- type: String,
12
- variance: Symbol,
13
- fixed: T.nilable(String),
14
- upper: T.nilable(String),
15
- lower: T.nilable(String)
16
- ).returns(String)
17
- end
18
- def self.serialize_type_variable(type, variance, fixed, upper, lower)
19
- variance = nil if variance == :invariant
20
-
21
- bounds = []
22
- bounds << "fixed: #{fixed}" if fixed
23
- bounds << "lower: #{lower}" if lower
24
- bounds << "upper: #{upper}" if upper
25
-
26
- parameters = []
27
- block = []
28
-
29
- parameters << ":#{variance}" if variance
30
-
31
- if sorbet_supports?(:type_variable_block_syntax)
32
- block = bounds
33
- else
34
- parameters.concat(bounds)
35
- end
36
-
37
- serialized = type.dup
38
- serialized << "(#{parameters.join(", ")})" unless parameters.empty?
39
- serialized << " { { #{block.join(", ")} } }" unless block.empty?
40
- serialized
41
- end
42
- end
43
- end