tapioca 0.6.1 → 0.7.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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +13 -2
  3. data/README.md +79 -25
  4. data/Rakefile +10 -14
  5. data/lib/tapioca/cli.rb +66 -80
  6. data/lib/tapioca/{generators/base.rb → commands/command.rb} +17 -10
  7. data/lib/tapioca/{generators → commands}/dsl.rb +59 -45
  8. data/lib/tapioca/{generators → commands}/gem.rb +93 -30
  9. data/lib/tapioca/{generators → commands}/init.rb +9 -13
  10. data/lib/tapioca/{generators → commands}/require.rb +8 -10
  11. data/lib/tapioca/commands/todo.rb +84 -0
  12. data/lib/tapioca/commands.rb +13 -0
  13. data/lib/tapioca/dsl/compiler.rb +185 -0
  14. data/lib/tapioca/{compilers/dsl → dsl/compilers}/aasm.rb +12 -9
  15. data/lib/tapioca/{compilers/dsl → dsl/compilers}/action_controller_helpers.rb +13 -20
  16. data/lib/tapioca/{compilers/dsl → dsl/compilers}/action_mailer.rb +10 -8
  17. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_job.rb +11 -9
  18. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_model_attributes.rb +32 -24
  19. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_model_secure_password.rb +10 -12
  20. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_associations.rb +29 -35
  21. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_columns.rb +26 -24
  22. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_enum.rb +14 -12
  23. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_fixtures.rb +10 -8
  24. data/lib/tapioca/dsl/compilers/active_record_relations.rb +712 -0
  25. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_scope.rb +21 -20
  26. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_typed_store.rb +12 -17
  27. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_resource.rb +10 -8
  28. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_storage.rb +11 -11
  29. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_support_concern.rb +19 -14
  30. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_support_current_attributes.rb +16 -21
  31. data/lib/tapioca/{compilers/dsl → dsl/compilers}/config.rb +10 -8
  32. data/lib/tapioca/{compilers/dsl → dsl/compilers}/frozen_record.rb +13 -11
  33. data/lib/tapioca/{compilers/dsl → dsl/compilers}/identity_cache.rb +28 -25
  34. data/lib/tapioca/{compilers/dsl → dsl/compilers}/mixed_in_class_attributes.rb +12 -10
  35. data/lib/tapioca/{compilers/dsl → dsl/compilers}/protobuf.rb +10 -8
  36. data/lib/tapioca/{compilers/dsl → dsl/compilers}/rails_generators.rb +13 -14
  37. data/lib/tapioca/{compilers/dsl → dsl/compilers}/sidekiq_worker.rb +14 -13
  38. data/lib/tapioca/{compilers/dsl → dsl/compilers}/smart_properties.rb +12 -13
  39. data/lib/tapioca/{compilers/dsl → dsl/compilers}/state_machines.rb +12 -10
  40. data/lib/tapioca/{compilers/dsl → dsl/compilers}/url_helpers.rb +16 -14
  41. data/lib/tapioca/dsl/compilers.rb +31 -0
  42. data/lib/tapioca/{compilers/dsl → dsl}/extensions/frozen_record.rb +2 -2
  43. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +114 -0
  44. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +29 -0
  45. data/lib/tapioca/{compilers/dsl → dsl/helpers}/param_helper.rb +2 -2
  46. data/lib/tapioca/{compilers/dsl_compiler.rb → dsl/pipeline.rb} +41 -33
  47. data/lib/tapioca/gem/events.rb +120 -0
  48. data/lib/tapioca/gem/listeners/base.rb +48 -0
  49. data/lib/tapioca/gem/listeners/dynamic_mixins.rb +32 -0
  50. data/lib/tapioca/gem/listeners/methods.rb +183 -0
  51. data/lib/tapioca/gem/listeners/mixins.rb +101 -0
  52. data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +21 -0
  53. data/lib/tapioca/gem/listeners/sorbet_enums.rb +26 -0
  54. data/lib/tapioca/gem/listeners/sorbet_helpers.rb +29 -0
  55. data/lib/tapioca/gem/listeners/sorbet_props.rb +33 -0
  56. data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +23 -0
  57. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +79 -0
  58. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +51 -0
  59. data/lib/tapioca/gem/listeners/subconstants.rb +37 -0
  60. data/lib/tapioca/gem/listeners/yard_doc.rb +96 -0
  61. data/lib/tapioca/gem/listeners.rb +16 -0
  62. data/lib/tapioca/gem/pipeline.rb +365 -0
  63. data/lib/tapioca/gemfile.rb +44 -20
  64. data/lib/tapioca/helpers/cli_helper.rb +16 -8
  65. data/lib/tapioca/helpers/config_helper.rb +113 -0
  66. data/lib/tapioca/helpers/rbi_helper.rb +17 -0
  67. data/lib/tapioca/helpers/shims_helper.rb +87 -0
  68. data/lib/tapioca/helpers/sorbet_helper.rb +57 -0
  69. data/lib/tapioca/helpers/test/dsl_compiler.rb +118 -0
  70. data/lib/tapioca/helpers/test/isolation.rb +1 -1
  71. data/lib/tapioca/helpers/test/template.rb +13 -2
  72. data/lib/tapioca/internal.rb +17 -10
  73. data/lib/tapioca/rbi_ext/model.rb +2 -48
  74. data/lib/tapioca/rbi_formatter.rb +37 -0
  75. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +227 -0
  76. data/lib/tapioca/runtime/generic_type_registry.rb +166 -0
  77. data/lib/tapioca/runtime/loader.rb +123 -0
  78. data/lib/tapioca/runtime/reflection.rb +153 -0
  79. data/lib/tapioca/runtime/trackers/autoload.rb +72 -0
  80. data/lib/tapioca/runtime/trackers/constant_definition.rb +44 -0
  81. data/lib/tapioca/runtime/trackers/mixin.rb +80 -0
  82. data/lib/tapioca/runtime/trackers/required_ancestor.rb +50 -0
  83. data/lib/tapioca/{trackers.rb → runtime/trackers.rb} +4 -3
  84. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +110 -54
  85. data/lib/tapioca/sorbet_ext/name_patch.rb +7 -1
  86. data/lib/tapioca/{compilers → static}/requires_compiler.rb +5 -12
  87. data/lib/tapioca/static/symbol_loader.rb +83 -0
  88. data/lib/tapioca/static/symbol_table_parser.rb +63 -0
  89. data/lib/tapioca/version.rb +1 -1
  90. data/lib/tapioca.rb +2 -7
  91. metadata +82 -62
  92. data/lib/tapioca/compilers/dsl/active_record_relations.rb +0 -711
  93. data/lib/tapioca/compilers/dsl/base.rb +0 -179
  94. data/lib/tapioca/compilers/dsl/helper/active_record_constants.rb +0 -27
  95. data/lib/tapioca/compilers/dynamic_mixin_compiler.rb +0 -198
  96. data/lib/tapioca/compilers/sorbet.rb +0 -59
  97. data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +0 -780
  98. data/lib/tapioca/compilers/symbol_table/symbol_loader.rb +0 -90
  99. data/lib/tapioca/compilers/symbol_table_compiler.rb +0 -17
  100. data/lib/tapioca/compilers/todos_compiler.rb +0 -32
  101. data/lib/tapioca/generators/todo.rb +0 -76
  102. data/lib/tapioca/generators.rb +0 -9
  103. data/lib/tapioca/generic_type_registry.rb +0 -149
  104. data/lib/tapioca/helpers/active_record_column_type_helper.rb +0 -98
  105. data/lib/tapioca/loader.rb +0 -119
  106. data/lib/tapioca/reflection.rb +0 -151
  107. data/lib/tapioca/trackers/autoload.rb +0 -70
  108. data/lib/tapioca/trackers/constant_definition.rb +0 -42
  109. data/lib/tapioca/trackers/mixin.rb +0 -78
@@ -17,23 +17,37 @@ module T
17
17
  constant = super
18
18
  # `register_type` method builds and returns an instantiated clone of the generic type
19
19
  # so, we just return that from this method as well.
20
- Tapioca::GenericTypeRegistry.register_type(constant, types)
20
+ Tapioca::Runtime::GenericTypeRegistry.register_type(constant, types)
21
21
  end
22
22
 
23
23
  def type_member(variance = :invariant, fixed: nil, lower: T.untyped, upper: BasicObject)
24
24
  # `T::Generic#type_member` just instantiates a `T::Type::TypeMember` instance and returns it.
25
25
  # We use that when registering the type member and then later return it from this method.
26
- type_member = Tapioca::TypeMember.new(variance, fixed, lower, upper)
27
- Tapioca::GenericTypeRegistry.register_type_variable(self, type_member)
28
- type_member
26
+ Tapioca::TypeVariableModule.new(
27
+ T.cast(self, Module),
28
+ Tapioca::TypeVariableModule::Type::Member,
29
+ variance,
30
+ fixed,
31
+ lower,
32
+ upper
33
+ ).tap do |type_variable|
34
+ Tapioca::Runtime::GenericTypeRegistry.register_type_variable(self, type_variable)
35
+ end
29
36
  end
30
37
 
31
38
  def type_template(variance = :invariant, fixed: nil, lower: T.untyped, upper: BasicObject)
32
39
  # `T::Generic#type_template` just instantiates a `T::Type::TypeTemplate` instance and returns it.
33
40
  # We use that when registering the type template and then later return it from this method.
34
- type_template = Tapioca::TypeTemplate.new(variance, fixed, lower, upper)
35
- Tapioca::GenericTypeRegistry.register_type_variable(self, type_template)
36
- type_template
41
+ Tapioca::TypeVariableModule.new(
42
+ T.cast(self, Module),
43
+ Tapioca::TypeVariableModule::Type::Template,
44
+ variance,
45
+ fixed,
46
+ lower,
47
+ upper
48
+ ).tap do |type_variable|
49
+ Tapioca::Runtime::GenericTypeRegistry.register_type_variable(self, type_variable)
50
+ end
37
51
  end
38
52
  end
39
53
 
@@ -42,15 +56,14 @@ module T
42
56
 
43
57
  module Types
44
58
  class Simple
45
- # This module intercepts calls to the `name` method for
46
- # simple types, so that it can ask the name to the type if
47
- # the type is generic, since, by this point, we've created
48
- # a clone of that type with the `name` method returning the
49
- # appropriate name for that specific concrete type.
50
- module GenericNamePatch
59
+ module GenericPatch
60
+ # This method intercepts calls to the `name` method for simple types, so that
61
+ # it can ask the name to the type if the type is generic, since, by this point,
62
+ # we've created a clone of that type with the `name` method returning the
63
+ # appropriate name for that specific concrete type.
51
64
  def name
52
- if T::Generic === @raw_type
53
- # for types that are generic, use the name
65
+ if T::Generic === @raw_type || Tapioca::TypeVariableModule === @raw_type
66
+ # for types that are generic or are type variables, use the name
54
67
  # returned by the "name" method of this instance
55
68
  @name ||= T.unsafe(@raw_type).name.freeze
56
69
  else
@@ -60,60 +73,82 @@ module T
60
73
  end
61
74
  end
62
75
 
63
- prepend GenericNamePatch
76
+ prepend GenericPatch
64
77
  end
65
78
  end
66
- end
67
-
68
- module Tapioca
69
- class TypeMember < T::Types::TypeMember
70
- extend T::Sig
71
79
 
72
- sig { returns(T.nilable(String)) }
73
- attr_accessor :name
80
+ module Utils
81
+ module CoercePatch
82
+ def coerce(val)
83
+ if val.is_a?(Tapioca::TypeVariableModule)
84
+ val.coerce_to_type_variable
85
+ else
86
+ super
87
+ end
88
+ end
89
+ end
74
90
 
75
- sig { returns(T.untyped) }
76
- attr_reader :fixed, :lower, :upper
91
+ class << self
92
+ prepend(CoercePatch)
93
+ end
94
+ end
95
+ end
77
96
 
78
- sig { params(variance: Symbol, fixed: T.untyped, lower: T.untyped, upper: T.untyped).void }
79
- def initialize(variance, fixed, lower, upper)
97
+ module Tapioca
98
+ class TypeVariable < ::T::Types::TypeVariable
99
+ def initialize(name, variance)
100
+ @name = name
80
101
  super(variance)
81
- @fixed = fixed
82
- @lower = lower
83
- @upper = upper
84
102
  end
85
103
 
86
- sig { returns(String) }
87
- def serialize
88
- parts = []
89
- parts << ":#{@variance}" unless @variance == :invariant
90
- parts << "fixed: #{@fixed}" if @fixed
91
- parts << "lower: #{@lower}" unless @lower == T.untyped
92
- parts << "upper: #{@upper}" unless @upper == BasicObject
93
-
94
- parameters = parts.join(", ")
95
-
96
- serialized = +"type_member"
97
- serialized << "(#{parameters})" unless parameters.empty?
98
- serialized
99
- end
104
+ attr_reader :name
100
105
  end
101
106
 
102
- class TypeTemplate < T::Types::TypeTemplate
107
+ # This is subclassing from `Module` so that instances of this type will be modules.
108
+ # The reason why we want that is because that means those instances will automatically
109
+ # get bound to the constant names they are assigned to by Ruby. As a result, we don't
110
+ # need to do any matching of constants to type variables to bind their names, Ruby will
111
+ # do that automatically for us and we get the `name` method for free from `Module`.
112
+ class TypeVariableModule < Module
103
113
  extend T::Sig
104
114
 
105
- sig { returns(T.nilable(String)) }
106
- attr_accessor :name
107
-
108
- sig { returns(T.untyped) }
109
- attr_reader :fixed, :lower, :upper
115
+ class Type < T::Enum
116
+ enums do
117
+ Member = new("type_member")
118
+ Template = new("type_template")
119
+ end
120
+ end
110
121
 
111
- sig { params(variance: Symbol, fixed: T.untyped, lower: T.untyped, upper: T.untyped).void }
112
- def initialize(variance, fixed, lower, upper)
113
- super(variance)
122
+ sig do
123
+ params(context: Module, type: Type, variance: Symbol, fixed: T.untyped, lower: T.untyped, upper: T.untyped).void
124
+ end
125
+ def initialize(context, type, variance, fixed, lower, upper) # rubocop:disable Metrics/ParameterLists
126
+ @context = context
127
+ @type = type
128
+ @variance = variance
114
129
  @fixed = fixed
115
130
  @lower = lower
116
131
  @upper = upper
132
+ super()
133
+ end
134
+
135
+ sig { returns(T.nilable(String)) }
136
+ def name
137
+ constant_name = super
138
+
139
+ # This is a hack to work around modules under anonymous modules not having
140
+ # names in 2.6 and 2.7: https://bugs.ruby-lang.org/issues/14895
141
+ #
142
+ # This happens when a type variable is declared under `class << self`, for
143
+ # example.
144
+ #
145
+ # The workaround is to give the parent context a name, at which point, our
146
+ # module gets bound to a name under that name, as well.
147
+ unless constant_name
148
+ constant_name = with_bound_name_pre_3_0 { super }
149
+ end
150
+
151
+ constant_name&.split("::")&.last
117
152
  end
118
153
 
119
154
  sig { returns(String) }
@@ -126,9 +161,30 @@ module Tapioca
126
161
 
127
162
  parameters = parts.join(", ")
128
163
 
129
- serialized = +"type_template"
164
+ serialized = @type.serialize.dup
130
165
  serialized << "(#{parameters})" unless parameters.empty?
131
166
  serialized
132
167
  end
168
+
169
+ sig { returns(Tapioca::TypeVariable) }
170
+ def coerce_to_type_variable
171
+ TypeVariable.new(name, @variance)
172
+ end
173
+
174
+ private
175
+
176
+ sig do
177
+ type_parameters(:Result)
178
+ .params(block: T.proc.returns(T.type_parameter(:Result)))
179
+ .returns(T.type_parameter(:Result))
180
+ end
181
+ def with_bound_name_pre_3_0(&block)
182
+ require "securerandom"
183
+ temp_name = "TYPE_VARIABLE_TRACKING_#{SecureRandom.hex}"
184
+ self.class.const_set(temp_name, @context)
185
+ block.call
186
+ ensure
187
+ self.class.send(:remove_const, temp_name) if temp_name
188
+ end
133
189
  end
134
190
  end
@@ -1,12 +1,18 @@
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
+
4
8
  module T
5
9
  module Types
6
10
  class Simple
7
11
  module NamePatch
8
12
  def name
9
- @name ||= ::Tapioca::Reflection.name_of(@raw_type).freeze
13
+ # Sorbet memoizes this method into the `@name` instance variable but
14
+ # doing so means that types get memoized before this patch is applied
15
+ ::Tapioca::Runtime::Reflection.qualified_name_of(@raw_type)
10
16
  end
11
17
  end
12
18
 
@@ -4,7 +4,7 @@
4
4
  require "spoom"
5
5
 
6
6
  module Tapioca
7
- module Compilers
7
+ module Static
8
8
  class RequiresCompiler
9
9
  extend T::Sig
10
10
 
@@ -17,10 +17,9 @@ module Tapioca
17
17
  def compile
18
18
  config = Spoom::Sorbet::Config.parse_file(@sorbet_path)
19
19
  files = collect_files(config)
20
+ names_in_project = files.to_h { |file| [File.basename(file, ".rb"), true] }
20
21
  files.flat_map do |file|
21
- collect_requires(file).reject do |req|
22
- name_in_project?(files, req)
23
- end
22
+ collect_requires(file).reject { |req| names_in_project[req] }
24
23
  end.sort.uniq.map do |name|
25
24
  "require \"#{name}\"\n"
26
25
  end.join
@@ -45,9 +44,10 @@ module Tapioca
45
44
 
46
45
  sig { params(file_path: String).returns(T::Enumerable[String]) }
47
46
  def collect_requires(file_path)
48
- File.read(file_path).lines.map do |line|
47
+ File.binread(file_path).lines.map do |line|
49
48
  /^\s*require\s*(\(\s*)?['"](?<name>[^'"]+)['"](\s*\))?/.match(line) { |m| m["name"] }
50
49
  end.compact
50
+ .reject { |require| require.include?('#{') } # ignore interpolation
51
51
  end
52
52
 
53
53
  sig { params(config: Spoom::Sorbet::Config, file_path: Pathname).returns(T::Boolean) }
@@ -83,13 +83,6 @@ module Tapioca
83
83
  def path_parts(path)
84
84
  T.unsafe(path).descend.map { |part| part.basename.to_s }
85
85
  end
86
-
87
- sig { params(files: T::Enumerable[String], name: String).returns(T::Boolean) }
88
- def name_in_project?(files, name)
89
- files.any? do |file|
90
- File.basename(file, ".rb") == name
91
- end
92
- end
93
86
  end
94
87
  end
95
88
  end
@@ -0,0 +1,83 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "json"
5
+ require "tempfile"
6
+
7
+ module Tapioca
8
+ module Static
9
+ module SymbolLoader
10
+ class << self
11
+ extend T::Sig
12
+ include SorbetHelper
13
+ include Runtime::Reflection
14
+
15
+ sig { returns(T::Set[String]) }
16
+ def payload_symbols
17
+ unless @payload_symbols
18
+ output = symbol_table_json_from("-e ''", table_type: "symbol-table-full-json")
19
+ @payload_symbols = T.let(SymbolTableParser.parse_json(output), T.nilable(T::Set[String]))
20
+ end
21
+
22
+ T.must(@payload_symbols)
23
+ end
24
+
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]))
29
+ end
30
+ T.must(@engine_symbols)
31
+ end
32
+
33
+ sig { params(gem: Gemfile::GemSpec).returns(T::Set[String]) }
34
+ def gem_symbols(gem)
35
+ symbols_from_paths(gem.files)
36
+ end
37
+
38
+ private
39
+
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
55
+
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")
60
+ end
61
+
62
+ symbols_from_paths(paths)
63
+ rescue
64
+ Set.new
65
+ end
66
+
67
+ sig { params(paths: T::Array[Pathname]).returns(T::Set[String]) }
68
+ def symbols_from_paths(paths)
69
+ output = T.cast(Tempfile.create("sorbet") do |file|
70
+ file.write(Array(paths).join("\n"))
71
+ file.flush
72
+
73
+ symbol_table_json_from("@#{file.path.shellescape}")
74
+ end, T.nilable(String))
75
+
76
+ return Set.new if output.nil? || output.empty?
77
+
78
+ SymbolTableParser.parse_json(output)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,63 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "json"
5
+ require "tempfile"
6
+
7
+ module Tapioca
8
+ module Static
9
+ class SymbolTableParser
10
+ extend T::Sig
11
+
12
+ sig { params(json_string: String).returns(T::Set[String]) }
13
+ def self.parse_json(json_string)
14
+ obj = JSON.parse(json_string)
15
+
16
+ parser = SymbolTableParser.new
17
+ parser.parse_object(obj)
18
+ parser.symbols
19
+ end
20
+
21
+ sig { returns(T::Set[String]) }
22
+ attr_reader :symbols
23
+
24
+ sig { void }
25
+ def initialize
26
+ @symbols = T.let(Set.new, T::Set[String])
27
+ @parents = T.let([], T::Array[String])
28
+ end
29
+
30
+ sig { params(object: T::Hash[String, T.untyped]).void }
31
+ def parse_object(object)
32
+ children = object.fetch("children", [])
33
+
34
+ children.each do |child|
35
+ kind = child.fetch("kind")
36
+ name = child.fetch("name")
37
+ name = name.fetch("name") if name.is_a?(Hash)
38
+
39
+ next if kind.nil? || name.nil?
40
+
41
+ # TODO: CLASS is removed since v0.4.4730 of Sorbet
42
+ # but keeping here for backward compatibility. Remove
43
+ # once the minimum version is moved past that.
44
+ next unless ["CLASS", "CLASS_OR_MODULE", "STATIC_FIELD"].include?(kind)
45
+ next if name =~ /[<>()$]/
46
+ next if name =~ /^[0-9]+$/
47
+ next if name == "T::Helpers"
48
+
49
+ @symbols.add(fully_qualified_name(name))
50
+
51
+ @parents << name
52
+ parse_object(child)
53
+ @parents.pop
54
+ end
55
+ end
56
+
57
+ sig { params(name: String).returns(String) }
58
+ def fully_qualified_name(name)
59
+ [*@parents, name].join("::")
60
+ end
61
+ end
62
+ end
63
+ end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.6.1"
5
+ VERSION = "0.7.0"
6
6
  end
data/lib/tapioca.rb CHANGED
@@ -14,7 +14,7 @@ module Tapioca
14
14
  def self.silence_warnings(&blk)
15
15
  original_verbosity = $VERBOSE
16
16
  $VERBOSE = nil
17
- Gem::DefaultUserInteraction.use_ui(Gem::SilentUI.new) do
17
+ ::Gem::DefaultUserInteraction.use_ui(::Gem::SilentUI.new) do
18
18
  blk.call
19
19
  end
20
20
  ensure
@@ -28,7 +28,7 @@ module Tapioca
28
28
  TAPIOCA_DIR = T.let("#{SORBET_DIR}/tapioca", String)
29
29
  TAPIOCA_CONFIG_FILE = T.let("#{TAPIOCA_DIR}/config.yml", String)
30
30
 
31
- DEFAULT_COMMAND = T.let("bin/tapioca", String)
31
+ BINARY_FILE = T.let("bin/tapioca", String)
32
32
  DEFAULT_POSTREQUIRE_FILE = T.let("#{TAPIOCA_DIR}/require.rb", String)
33
33
  DEFAULT_RBI_DIR = T.let("#{SORBET_DIR}/rbi", String)
34
34
  DEFAULT_DSL_DIR = T.let("#{DEFAULT_RBI_DIR}/dsl", String)
@@ -43,9 +43,4 @@ module Tapioca
43
43
  }.freeze, T::Hash[String, String])
44
44
  end
45
45
 
46
- require "tapioca/reflection"
47
- require "tapioca/trackers"
48
- require "tapioca/compilers/dsl/base"
49
- require "tapioca/compilers/dynamic_mixin_compiler"
50
- require "tapioca/helpers/active_record_column_type_helper"
51
46
  require "tapioca/version"