tapioca 0.16.9 → 0.17.7
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.
- checksums.yaml +4 -4
- data/README.md +21 -0
- data/exe/tapioca +6 -1
- data/lib/ruby_lsp/tapioca/addon.rb +73 -43
- data/lib/ruby_lsp/tapioca/run_gem_rbi_check.rb +43 -43
- data/lib/ruby_lsp/tapioca/server_addon.rb +13 -10
- data/lib/tapioca/bundler_ext/auto_require_hook.rb +6 -14
- data/lib/tapioca/cli.rb +16 -8
- data/lib/tapioca/commands/abstract_dsl.rb +39 -66
- data/lib/tapioca/commands/abstract_gem.rb +25 -46
- data/lib/tapioca/commands/annotations.rb +28 -34
- data/lib/tapioca/commands/check_shims.rb +6 -15
- data/lib/tapioca/commands/command.rb +12 -26
- data/lib/tapioca/commands/command_without_tracker.rb +2 -5
- data/lib/tapioca/commands/configure.rb +11 -16
- data/lib/tapioca/commands/dsl_compiler_list.rb +2 -1
- data/lib/tapioca/commands/dsl_generate.rb +2 -1
- data/lib/tapioca/commands/dsl_verify.rb +2 -1
- data/lib/tapioca/commands/gem_generate.rb +5 -9
- data/lib/tapioca/commands/gem_sync.rb +2 -1
- data/lib/tapioca/commands/gem_verify.rb +3 -2
- data/lib/tapioca/commands/require.rb +3 -7
- data/lib/tapioca/commands/todo.rb +6 -10
- data/lib/tapioca/dsl/compiler.rb +36 -63
- data/lib/tapioca/dsl/compilers/aasm.rb +33 -44
- data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +8 -7
- data/lib/tapioca/dsl/compilers/action_mailer.rb +6 -5
- data/lib/tapioca/dsl/compilers/action_text.rb +6 -5
- data/lib/tapioca/dsl/compilers/active_job.rb +6 -10
- data/lib/tapioca/dsl/compilers/active_model_attributes.rb +10 -11
- data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +5 -6
- data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +5 -12
- data/lib/tapioca/dsl/compilers/active_record_associations.rb +17 -44
- data/lib/tapioca/dsl/compilers/active_record_columns.rb +20 -26
- data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +9 -8
- data/lib/tapioca/dsl/compilers/active_record_enum.rb +7 -6
- data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +54 -62
- data/lib/tapioca/dsl/compilers/active_record_relations.rb +148 -209
- data/lib/tapioca/dsl/compilers/active_record_scope.rb +8 -13
- data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +5 -4
- data/lib/tapioca/dsl/compilers/active_record_store.rb +5 -4
- data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +19 -28
- data/lib/tapioca/dsl/compilers/active_resource.rb +19 -21
- data/lib/tapioca/dsl/compilers/active_storage.rb +6 -14
- data/lib/tapioca/dsl/compilers/active_support_concern.rb +9 -8
- data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +8 -7
- data/lib/tapioca/dsl/compilers/active_support_time_ext.rb +5 -4
- data/lib/tapioca/dsl/compilers/config.rb +5 -4
- data/lib/tapioca/dsl/compilers/frozen_record.rb +7 -11
- data/lib/tapioca/dsl/compilers/graphql_input_object.rb +9 -10
- data/lib/tapioca/dsl/compilers/graphql_mutation.rb +6 -10
- data/lib/tapioca/dsl/compilers/identity_cache.rb +11 -39
- data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +9 -18
- data/lib/tapioca/dsl/compilers/kredis.rb +7 -8
- data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +5 -4
- data/lib/tapioca/dsl/compilers/protobuf.rb +13 -26
- data/lib/tapioca/dsl/compilers/rails_generators.rb +9 -11
- data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +23 -13
- data/lib/tapioca/dsl/compilers/smart_properties.rb +32 -38
- data/lib/tapioca/dsl/compilers/state_machines.rb +15 -26
- data/lib/tapioca/dsl/compilers/url_helpers.rb +10 -9
- data/lib/tapioca/dsl/compilers.rb +4 -7
- data/lib/tapioca/dsl/helpers/active_model_type_helper.rb +13 -16
- data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +13 -28
- data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +19 -15
- data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +5 -24
- data/lib/tapioca/dsl/pipeline.rb +30 -58
- data/lib/tapioca/executor.rb +6 -12
- data/lib/tapioca/gem/events.rb +24 -34
- data/lib/tapioca/gem/listeners/base.rb +7 -10
- data/lib/tapioca/gem/listeners/dynamic_mixins.rb +4 -2
- data/lib/tapioca/gem/listeners/foreign_constants.rb +5 -7
- data/lib/tapioca/gem/listeners/methods.rb +36 -47
- data/lib/tapioca/gem/listeners/mixins.rb +6 -18
- data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_enums.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_helpers.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_props.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_signatures.rb +7 -5
- data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +6 -4
- data/lib/tapioca/gem/listeners/source_location.rb +15 -8
- data/lib/tapioca/gem/listeners/subconstants.rb +5 -4
- data/lib/tapioca/gem/listeners/yard_doc.rb +30 -23
- data/lib/tapioca/gem/pipeline.rb +107 -91
- data/lib/tapioca/gem_info.rb +1 -1
- data/lib/tapioca/gemfile.rb +64 -73
- data/lib/tapioca/helpers/cli_helper.rb +4 -7
- data/lib/tapioca/helpers/config_helper.rb +17 -29
- data/lib/tapioca/helpers/env_helper.rb +2 -5
- data/lib/tapioca/helpers/gem_helper.rb +5 -5
- data/lib/tapioca/helpers/git_attributes.rb +3 -3
- data/lib/tapioca/helpers/rbi_files_helper.rb +76 -73
- data/lib/tapioca/helpers/rbi_helper.rb +14 -22
- data/lib/tapioca/helpers/sorbet_helper.rb +9 -18
- data/lib/tapioca/helpers/source_uri.rb +15 -25
- data/lib/tapioca/helpers/test/content.rb +7 -10
- data/lib/tapioca/helpers/test/dsl_compiler.rb +20 -33
- data/lib/tapioca/helpers/test/isolation.rb +10 -14
- data/lib/tapioca/helpers/test/template.rb +6 -11
- data/lib/tapioca/internal.rb +18 -8
- data/lib/tapioca/loaders/dsl.rb +11 -19
- data/lib/tapioca/loaders/gem.rb +6 -21
- data/lib/tapioca/loaders/loader.rb +21 -39
- data/lib/tapioca/rbi_ext/model.rb +12 -37
- data/lib/tapioca/rbi_formatter.rb +10 -19
- data/lib/tapioca/rbs/rewriter.rb +55 -0
- data/lib/tapioca/repo_index.rb +7 -9
- data/lib/tapioca/runtime/attached_class_of_32.rb +1 -1
- data/lib/tapioca/runtime/attached_class_of_legacy.rb +2 -5
- data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +23 -23
- data/lib/tapioca/runtime/generic_type_registry.rb +13 -23
- data/lib/tapioca/runtime/reflection.rb +81 -60
- data/lib/tapioca/runtime/source_location.rb +44 -0
- data/lib/tapioca/runtime/trackers/autoload.rb +7 -9
- data/lib/tapioca/runtime/trackers/constant_definition.rb +18 -14
- data/lib/tapioca/runtime/trackers/method_definition.rb +65 -0
- data/lib/tapioca/runtime/trackers/mixin.rb +8 -11
- data/lib/tapioca/runtime/trackers/required_ancestor.rb +3 -3
- data/lib/tapioca/runtime/trackers/tracker.rb +3 -6
- data/lib/tapioca/runtime/trackers.rb +5 -8
- data/lib/tapioca/sorbet_ext/generic_name_patch.rb +9 -15
- data/lib/tapioca/sorbet_ext/name_patch.rb +2 -2
- data/lib/tapioca/sorbet_ext/proc_bind_patch.rb +1 -1
- data/lib/tapioca/static/requires_compiler.rb +6 -6
- data/lib/tapioca/static/symbol_loader.rb +14 -16
- data/lib/tapioca/static/symbol_table_parser.rb +8 -8
- data/lib/tapioca/version.rb +1 -1
- data/lib/tapioca.rb +22 -29
- metadata +27 -10
|
@@ -4,18 +4,15 @@
|
|
|
4
4
|
module Tapioca
|
|
5
5
|
module Gem
|
|
6
6
|
module Listeners
|
|
7
|
+
# @abstract
|
|
7
8
|
class Base
|
|
8
9
|
extend T::Sig
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
abstract!
|
|
12
|
-
|
|
13
|
-
sig { params(pipeline: Pipeline).void }
|
|
10
|
+
#: (Pipeline pipeline) -> void
|
|
14
11
|
def initialize(pipeline)
|
|
15
12
|
@pipeline = pipeline
|
|
16
13
|
end
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
#: (NodeAdded event) -> void
|
|
19
16
|
def dispatch(event)
|
|
20
17
|
return if ignore?(event)
|
|
21
18
|
|
|
@@ -33,19 +30,19 @@ module Tapioca
|
|
|
33
30
|
|
|
34
31
|
private
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
#: (ConstNodeAdded event) -> void
|
|
37
34
|
def on_const(event)
|
|
38
35
|
end
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
#: (ScopeNodeAdded event) -> void
|
|
41
38
|
def on_scope(event)
|
|
42
39
|
end
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
#: (MethodNodeAdded event) -> void
|
|
45
42
|
def on_method(event)
|
|
46
43
|
end
|
|
47
44
|
|
|
48
|
-
|
|
45
|
+
#: (NodeAdded event) -> bool
|
|
49
46
|
def ignore?(event)
|
|
50
47
|
# Some listeners do not have to take any action on certain events. For example,
|
|
51
48
|
# almost every listener should skip ForeignScopeNodeAdded events in order not to generate
|
|
@@ -11,7 +11,8 @@ module Tapioca
|
|
|
11
11
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# @override
|
|
15
|
+
#: (ScopeNodeAdded event) -> void
|
|
15
16
|
def on_scope(event)
|
|
16
17
|
constant = event.constant
|
|
17
18
|
return if constant.is_a?(Class)
|
|
@@ -27,7 +28,8 @@ module Tapioca
|
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
# @override
|
|
32
|
+
#: (NodeAdded event) -> bool
|
|
31
33
|
def ignore?(event)
|
|
32
34
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
33
35
|
end
|
|
@@ -11,7 +11,8 @@ module Tapioca
|
|
|
11
11
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# @override
|
|
15
|
+
#: (ScopeNodeAdded event) -> void
|
|
15
16
|
def on_scope(event)
|
|
16
17
|
mixin = event.constant
|
|
17
18
|
return if Class === mixin # Classes can't be mixed into other constants
|
|
@@ -47,16 +48,13 @@ module Tapioca
|
|
|
47
48
|
end
|
|
48
49
|
end
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
params(
|
|
52
|
-
location: String,
|
|
53
|
-
).returns(T::Boolean)
|
|
54
|
-
end
|
|
51
|
+
#: (String location) -> bool
|
|
55
52
|
def mixed_in_by_gem?(location)
|
|
56
53
|
@pipeline.gem.contains_path?(location)
|
|
57
54
|
end
|
|
58
55
|
|
|
59
|
-
|
|
56
|
+
# @override
|
|
57
|
+
#: (NodeAdded event) -> bool
|
|
60
58
|
def ignore?(event)
|
|
61
59
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
62
60
|
end
|
|
@@ -12,7 +12,8 @@ module Tapioca
|
|
|
12
12
|
|
|
13
13
|
private
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
# @override
|
|
16
|
+
#: (ScopeNodeAdded event) -> void
|
|
16
17
|
def on_scope(event)
|
|
17
18
|
symbol = event.symbol
|
|
18
19
|
constant = event.constant
|
|
@@ -23,15 +24,7 @@ module Tapioca
|
|
|
23
24
|
compile_directly_owned_methods(node, symbol, singleton_class_of(constant), attached_class: constant)
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
params(
|
|
28
|
-
tree: RBI::Tree,
|
|
29
|
-
module_name: String,
|
|
30
|
-
mod: Module,
|
|
31
|
-
for_visibility: T::Array[Symbol],
|
|
32
|
-
attached_class: T.nilable(Module),
|
|
33
|
-
).void
|
|
34
|
-
end
|
|
27
|
+
#: (RBI::Tree tree, String module_name, Module mod, ?Array[Symbol] for_visibility, ?attached_class: Module?) -> void
|
|
35
28
|
def compile_directly_owned_methods(
|
|
36
29
|
tree,
|
|
37
30
|
module_name,
|
|
@@ -59,29 +52,41 @@ module Tapioca
|
|
|
59
52
|
end
|
|
60
53
|
end
|
|
61
54
|
|
|
62
|
-
|
|
63
|
-
params(
|
|
64
|
-
tree: RBI::Tree,
|
|
65
|
-
symbol_name: String,
|
|
66
|
-
constant: Module,
|
|
67
|
-
method: T.nilable(UnboundMethod),
|
|
68
|
-
visibility: RBI::Visibility,
|
|
69
|
-
).void
|
|
70
|
-
end
|
|
55
|
+
#: (RBI::Tree tree, String symbol_name, Module constant, UnboundMethod? method, ?RBI::Visibility visibility) -> void
|
|
71
56
|
def compile_method(tree, symbol_name, constant, method, visibility = RBI::Public.new)
|
|
72
57
|
return unless method
|
|
73
58
|
return unless method_owned_by_constant?(method, constant)
|
|
74
|
-
return if @pipeline.symbol_in_payload?(symbol_name) && !@pipeline.method_in_gem?(method)
|
|
75
59
|
|
|
76
|
-
|
|
77
|
-
|
|
60
|
+
begin
|
|
61
|
+
signature = signature_of!(method)
|
|
62
|
+
method = signature.method if signature #: UnboundMethod
|
|
63
|
+
|
|
64
|
+
case @pipeline.method_definition_in_gem(method.name, constant)
|
|
65
|
+
when Pipeline::MethodUnknown
|
|
66
|
+
# This means that this is a C-method. Thus, we want to
|
|
67
|
+
# skip it only if the constant is an ignored one, since
|
|
68
|
+
# that probably means that we've hit a C-method for a
|
|
69
|
+
# core type.
|
|
70
|
+
return if @pipeline.symbol_in_payload?(symbol_name)
|
|
71
|
+
when Pipeline::MethodNotInGem
|
|
72
|
+
# Do not process this method, if it is not defined by the current gem
|
|
73
|
+
return
|
|
74
|
+
end
|
|
75
|
+
rescue SignatureBlockError => error
|
|
76
|
+
@pipeline.error_handler.call(<<~MSG)
|
|
77
|
+
Unable to compile signature for method: #{method.owner}##{method.name}
|
|
78
|
+
Exception raised when loading signature: #{error.cause.inspect}
|
|
79
|
+
MSG
|
|
80
|
+
|
|
81
|
+
signature = nil
|
|
82
|
+
end
|
|
78
83
|
|
|
79
84
|
method_name = method.name.to_s
|
|
80
85
|
return unless valid_method_name?(method_name)
|
|
81
86
|
return if struct_method?(constant, method_name)
|
|
82
87
|
return if method_name.start_with?("__t_props_generated_")
|
|
83
88
|
|
|
84
|
-
parameters =
|
|
89
|
+
parameters = method.parameters #: Array[[Symbol, Symbol?]]
|
|
85
90
|
|
|
86
91
|
sanitized_parameters = parameters.each_with_index.map do |(type, name), index|
|
|
87
92
|
fallback_arg_name = "_arg#{index}"
|
|
@@ -154,10 +159,10 @@ module Tapioca
|
|
|
154
159
|
# This method implements a better way of checking whether a constant defines a method.
|
|
155
160
|
# It walks up the ancestor tree via the `super_method` method; if any of the super
|
|
156
161
|
# methods are owned by the constant, it means that the constant declares the method.
|
|
157
|
-
|
|
162
|
+
#: (UnboundMethod method, Module constant) -> bool
|
|
158
163
|
def method_owned_by_constant?(method, constant)
|
|
159
164
|
# Widen the type of `method` to be nilable
|
|
160
|
-
method =
|
|
165
|
+
method = method #: UnboundMethod?
|
|
161
166
|
|
|
162
167
|
while method
|
|
163
168
|
return true if method.owner == constant
|
|
@@ -168,7 +173,7 @@ module Tapioca
|
|
|
168
173
|
false
|
|
169
174
|
end
|
|
170
175
|
|
|
171
|
-
|
|
176
|
+
#: (Module mod) -> Hash[Symbol, Array[Symbol]]
|
|
172
177
|
def method_names_by_visibility(mod)
|
|
173
178
|
{
|
|
174
179
|
public: public_instance_methods_of(mod),
|
|
@@ -177,7 +182,7 @@ module Tapioca
|
|
|
177
182
|
}
|
|
178
183
|
end
|
|
179
184
|
|
|
180
|
-
|
|
185
|
+
#: (Module constant, String method_name) -> bool
|
|
181
186
|
def struct_method?(constant, method_name)
|
|
182
187
|
return false unless T::Props::ClassMethods === constant
|
|
183
188
|
|
|
@@ -187,12 +192,7 @@ module Tapioca
|
|
|
187
192
|
.include?(method_name.gsub(/=$/, "").to_sym)
|
|
188
193
|
end
|
|
189
194
|
|
|
190
|
-
|
|
191
|
-
params(
|
|
192
|
-
attached_class: T.nilable(Module),
|
|
193
|
-
method_name: Symbol,
|
|
194
|
-
).returns(T.nilable(T::Boolean))
|
|
195
|
-
end
|
|
195
|
+
#: (Module? attached_class, Symbol method_name) -> bool?
|
|
196
196
|
def method_new_in_abstract_class?(attached_class, method_name)
|
|
197
197
|
attached_class &&
|
|
198
198
|
method_name == :new &&
|
|
@@ -200,29 +200,18 @@ module Tapioca
|
|
|
200
200
|
Class === attached_class.singleton_class
|
|
201
201
|
end
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
#: (Module constant) -> UnboundMethod?
|
|
204
204
|
def initialize_method_for(constant)
|
|
205
205
|
constant.instance_method(:initialize)
|
|
206
206
|
rescue
|
|
207
207
|
nil
|
|
208
208
|
end
|
|
209
209
|
|
|
210
|
-
|
|
210
|
+
# @override
|
|
211
|
+
#: (NodeAdded event) -> bool
|
|
211
212
|
def ignore?(event)
|
|
212
213
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
213
214
|
end
|
|
214
|
-
|
|
215
|
-
sig { params(method: UnboundMethod).returns(T.untyped) }
|
|
216
|
-
def lookup_signature_of(method)
|
|
217
|
-
signature_of!(method)
|
|
218
|
-
rescue LoadError, StandardError => error
|
|
219
|
-
@pipeline.error_handler.call(<<~MSG)
|
|
220
|
-
Unable to compile signature for method: #{method.owner}##{method.name}
|
|
221
|
-
Exception raised when loading signature: #{error.inspect}
|
|
222
|
-
MSG
|
|
223
|
-
|
|
224
|
-
nil
|
|
225
|
-
end
|
|
226
215
|
end
|
|
227
216
|
end
|
|
228
217
|
end
|
|
@@ -11,7 +11,8 @@ module Tapioca
|
|
|
11
11
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# @override
|
|
15
|
+
#: (ScopeNodeAdded event) -> void
|
|
15
16
|
def on_scope(event)
|
|
16
17
|
constant = event.constant
|
|
17
18
|
singleton_class = singleton_class_of(constant)
|
|
@@ -31,14 +32,7 @@ module Tapioca
|
|
|
31
32
|
add_mixins(node, constant, extends.reverse, Runtime::Trackers::Mixin::Type::Extend)
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
params(
|
|
36
|
-
tree: RBI::Tree,
|
|
37
|
-
constant: Module,
|
|
38
|
-
mods: T::Array[Module],
|
|
39
|
-
mixin_type: Runtime::Trackers::Mixin::Type,
|
|
40
|
-
).void
|
|
41
|
-
end
|
|
35
|
+
#: (RBI::Tree tree, Module constant, Array[Module] mods, Runtime::Trackers::Mixin::Type mixin_type) -> void
|
|
42
36
|
def add_mixins(tree, constant, mods, mixin_type)
|
|
43
37
|
mods
|
|
44
38
|
.select do |mod|
|
|
@@ -65,13 +59,7 @@ module Tapioca
|
|
|
65
59
|
end
|
|
66
60
|
end
|
|
67
61
|
|
|
68
|
-
|
|
69
|
-
params(
|
|
70
|
-
constant: Module,
|
|
71
|
-
mixin: Module,
|
|
72
|
-
mixin_type: Runtime::Trackers::Mixin::Type,
|
|
73
|
-
).returns(T::Boolean)
|
|
74
|
-
end
|
|
62
|
+
#: (Module constant, Module mixin, Runtime::Trackers::Mixin::Type mixin_type) -> bool
|
|
75
63
|
def mixed_in_by_gem?(constant, mixin, mixin_type)
|
|
76
64
|
mixin_location = Runtime::Trackers::Mixin.mixin_location(mixin, mixin_type, constant)
|
|
77
65
|
|
|
@@ -80,14 +68,14 @@ module Tapioca
|
|
|
80
68
|
@pipeline.gem.contains_path?(mixin_location)
|
|
81
69
|
end
|
|
82
70
|
|
|
83
|
-
|
|
71
|
+
#: (String mixin_name) -> bool
|
|
84
72
|
def filtered_mixin?(mixin_name)
|
|
85
73
|
# filter T:: namespace mixins that aren't T::Props
|
|
86
74
|
# T::Props and subconstants have semantic value
|
|
87
75
|
mixin_name.start_with?("T::") && !mixin_name.start_with?("T::Props")
|
|
88
76
|
end
|
|
89
77
|
|
|
90
|
-
|
|
78
|
+
#: (Module constant) -> Array[Module]
|
|
91
79
|
def interesting_ancestors_of(constant)
|
|
92
80
|
inherited_ancestors = Set.new.compare_by_identity.merge(inherited_ancestors_of(constant))
|
|
93
81
|
|
|
@@ -11,12 +11,14 @@ module Tapioca
|
|
|
11
11
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# @override
|
|
15
|
+
#: (ScopeNodeAdded event) -> void
|
|
15
16
|
def on_scope(event)
|
|
16
17
|
event.node.detach if @pipeline.symbol_in_payload?(event.symbol) && event.node.empty?
|
|
17
18
|
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
# @override
|
|
21
|
+
#: (NodeAdded event) -> bool
|
|
20
22
|
def ignore?(event)
|
|
21
23
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
22
24
|
end
|
|
@@ -9,7 +9,8 @@ module Tapioca
|
|
|
9
9
|
|
|
10
10
|
private
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
# @override
|
|
13
|
+
#: (ScopeNodeAdded event) -> void
|
|
13
14
|
def on_scope(event)
|
|
14
15
|
constant = event.constant
|
|
15
16
|
return unless T::Enum > event.constant # rubocop:disable Style/InvertibleUnlessCondition
|
|
@@ -24,7 +25,8 @@ module Tapioca
|
|
|
24
25
|
event.node << enum_block
|
|
25
26
|
end
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
# @override
|
|
29
|
+
#: (NodeAdded event) -> bool
|
|
28
30
|
def ignore?(event)
|
|
29
31
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
30
32
|
end
|
|
@@ -11,7 +11,8 @@ module Tapioca
|
|
|
11
11
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# @override
|
|
15
|
+
#: (ScopeNodeAdded event) -> void
|
|
15
16
|
def on_scope(event)
|
|
16
17
|
constant = event.constant
|
|
17
18
|
node = event.node
|
|
@@ -23,7 +24,8 @@ module Tapioca
|
|
|
23
24
|
node << RBI::Helper.new("sealed") if sealed_module?(constant)
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
# @override
|
|
28
|
+
#: (NodeAdded event) -> bool
|
|
27
29
|
def ignore?(event)
|
|
28
30
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
29
31
|
end
|
|
@@ -10,7 +10,8 @@ module Tapioca
|
|
|
10
10
|
|
|
11
11
|
private
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
# @override
|
|
14
|
+
#: (ScopeNodeAdded event) -> void
|
|
14
15
|
def on_scope(event)
|
|
15
16
|
constant = event.constant
|
|
16
17
|
node = event.node
|
|
@@ -29,7 +30,8 @@ module Tapioca
|
|
|
29
30
|
end
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
# @override
|
|
34
|
+
#: (NodeAdded event) -> bool
|
|
33
35
|
def ignore?(event)
|
|
34
36
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
35
37
|
end
|
|
@@ -9,7 +9,8 @@ module Tapioca
|
|
|
9
9
|
|
|
10
10
|
private
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
# @override
|
|
13
|
+
#: (ScopeNodeAdded event) -> void
|
|
13
14
|
def on_scope(event)
|
|
14
15
|
ancestors = Runtime::Trackers::RequiredAncestor.required_ancestors_by(event.constant)
|
|
15
16
|
ancestors.each do |ancestor|
|
|
@@ -19,7 +20,8 @@ module Tapioca
|
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
# @override
|
|
24
|
+
#: (NodeAdded event) -> bool
|
|
23
25
|
def ignore?(event)
|
|
24
26
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
25
27
|
end
|
|
@@ -14,7 +14,8 @@ module Tapioca
|
|
|
14
14
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
# @override
|
|
18
|
+
#: (MethodNodeAdded event) -> void
|
|
18
19
|
def on_method(event)
|
|
19
20
|
signature = event.signature
|
|
20
21
|
return unless signature
|
|
@@ -22,9 +23,9 @@ module Tapioca
|
|
|
22
23
|
event.node.sigs << compile_signature(signature, event.parameters)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
#: (untyped signature, Array[[Symbol, String]] parameters) -> RBI::Sig
|
|
26
27
|
def compile_signature(signature, parameters)
|
|
27
|
-
parameter_types =
|
|
28
|
+
parameter_types = signature.arg_types.to_h #: Hash[Symbol, T::Types::Base]
|
|
28
29
|
parameter_types.merge!(signature.kwarg_types)
|
|
29
30
|
parameter_types[signature.rest_name] = signature.rest_type if signature.has_rest
|
|
30
31
|
parameter_types[signature.keyrest_name] = signature.keyrest_type if signature.has_keyrest
|
|
@@ -64,7 +65,7 @@ module Tapioca
|
|
|
64
65
|
sig
|
|
65
66
|
end
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
#: (untyped signature) -> bool
|
|
68
69
|
def signature_final?(signature)
|
|
69
70
|
modules_with_final = T::Private::Methods.instance_variable_get(:@modules_with_final)
|
|
70
71
|
# In https://github.com/sorbet/sorbet/pull/7531, Sorbet changed internal hashes to be compared by identity,
|
|
@@ -75,7 +76,8 @@ module Tapioca
|
|
|
75
76
|
final_methods.include?(signature.method_name)
|
|
76
77
|
end
|
|
77
78
|
|
|
78
|
-
|
|
79
|
+
# @override
|
|
80
|
+
#: (NodeAdded event) -> bool
|
|
79
81
|
def ignore?(event)
|
|
80
82
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
81
83
|
end
|
|
@@ -11,7 +11,8 @@ module Tapioca
|
|
|
11
11
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# @override
|
|
15
|
+
#: (ScopeNodeAdded event) -> void
|
|
15
16
|
def on_scope(event)
|
|
16
17
|
constant = event.constant
|
|
17
18
|
node = event.node
|
|
@@ -23,7 +24,7 @@ module Tapioca
|
|
|
23
24
|
node << sclass if sclass.nodes.length > 1
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
#: (RBI::Tree tree, Module constant) -> void
|
|
27
28
|
def compile_type_variable_declarations(tree, constant)
|
|
28
29
|
# Try to find the type variables defined on this constant, bail if we can't
|
|
29
30
|
type_variables = Runtime::GenericTypeRegistry.lookup_type_variables(constant)
|
|
@@ -46,7 +47,7 @@ module Tapioca
|
|
|
46
47
|
tree << RBI::Extend.new("T::Generic")
|
|
47
48
|
end
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
#: (Tapioca::TypeVariableModule type_variable) -> RBI::Node?
|
|
50
51
|
def node_from_type_variable(type_variable)
|
|
51
52
|
case type_variable.type
|
|
52
53
|
when Tapioca::TypeVariableModule::Type::HasAttachedClass
|
|
@@ -59,7 +60,8 @@ module Tapioca
|
|
|
59
60
|
end
|
|
60
61
|
end
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
# @override
|
|
64
|
+
#: (NodeAdded event) -> bool
|
|
63
65
|
def ignore?(event)
|
|
64
66
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
65
67
|
end
|
|
@@ -9,35 +9,42 @@ module Tapioca
|
|
|
9
9
|
|
|
10
10
|
private
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
# @override
|
|
13
|
+
#: (ConstNodeAdded event) -> void
|
|
13
14
|
def on_const(event)
|
|
14
15
|
file, line = Object.const_source_location(event.symbol)
|
|
15
16
|
add_source_location_comment(event.node, file, line)
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
# @override
|
|
20
|
+
#: (ScopeNodeAdded event) -> void
|
|
19
21
|
def on_scope(event)
|
|
20
22
|
# Instead of using `const_source_location`, which always reports the first place where a constant is defined,
|
|
21
23
|
# we filter the locations tracked by ConstantDefinition. This allows us to provide the correct location for
|
|
22
24
|
# constants that are defined by multiple gems.
|
|
23
25
|
locations = Runtime::Trackers::ConstantDefinition.locations_for(event.constant)
|
|
24
26
|
location = locations.find do |loc|
|
|
25
|
-
Pathname.new(loc.
|
|
27
|
+
Pathname.new(loc.file).realpath.to_s.include?(@pipeline.gem.full_gem_path)
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
# The location may still be nil in some situations, like constant aliases (e.g.: MyAlias = OtherConst). These
|
|
29
31
|
# are quite difficult to attribute a correct location, given that the source location points to the original
|
|
30
32
|
# constants and not the alias
|
|
31
|
-
add_source_location_comment(event.node, location.
|
|
33
|
+
add_source_location_comment(event.node, location.file, location.line) unless location.nil?
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
# @override
|
|
37
|
+
#: (MethodNodeAdded event) -> void
|
|
35
38
|
def on_method(event)
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
definition = @pipeline.method_definition_in_gem(event.method.name, event.constant)
|
|
40
|
+
|
|
41
|
+
if Pipeline::MethodInGemWithLocation === definition
|
|
42
|
+
loc = definition.location
|
|
43
|
+
add_source_location_comment(event.node, loc.file, loc.line)
|
|
44
|
+
end
|
|
38
45
|
end
|
|
39
46
|
|
|
40
|
-
|
|
47
|
+
#: (RBI::NodeWithComments node, String? file, Integer? line) -> void
|
|
41
48
|
def add_source_location_comment(node, file, line)
|
|
42
49
|
return unless file && line
|
|
43
50
|
|
|
@@ -11,14 +11,14 @@ module Tapioca
|
|
|
11
11
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# @override
|
|
15
|
+
#: (ScopeNodeAdded event) -> void
|
|
15
16
|
def on_scope(event)
|
|
16
17
|
symbol = event.symbol
|
|
17
|
-
|
|
18
|
+
constant = event.constant
|
|
18
19
|
|
|
19
20
|
prefix = symbol == "Object" ? "" : symbol
|
|
20
21
|
|
|
21
|
-
constant = event.constant
|
|
22
22
|
constants_of(constant).sort.uniq.map do |constant_name|
|
|
23
23
|
name = "#{prefix}::#{constant_name}"
|
|
24
24
|
subconstant = constantize(name)
|
|
@@ -32,7 +32,8 @@ module Tapioca
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
# @override
|
|
36
|
+
#: (NodeAdded event) -> bool
|
|
36
37
|
def ignore?(event)
|
|
37
38
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
38
39
|
end
|
|
@@ -7,23 +7,21 @@ module Tapioca
|
|
|
7
7
|
class YardDoc < Base
|
|
8
8
|
extend T::Sig
|
|
9
9
|
|
|
10
|
-
IGNORED_COMMENTS =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
sig { params(pipeline: Pipeline).void }
|
|
10
|
+
IGNORED_COMMENTS = [
|
|
11
|
+
":doc:",
|
|
12
|
+
":nodoc:",
|
|
13
|
+
"typed:",
|
|
14
|
+
"frozen_string_literal:",
|
|
15
|
+
"encoding:",
|
|
16
|
+
"warn_indent:",
|
|
17
|
+
"shareable_constant_value:",
|
|
18
|
+
"rubocop:",
|
|
19
|
+
"@requires_ancestor:",
|
|
20
|
+
] #: Array[String]
|
|
21
|
+
|
|
22
|
+
IGNORED_SIG_TAGS = ["param", "return"] #: Array[String]
|
|
23
|
+
|
|
24
|
+
#: (Pipeline pipeline) -> void
|
|
27
25
|
def initialize(pipeline)
|
|
28
26
|
YARD::Registry.clear
|
|
29
27
|
super(pipeline)
|
|
@@ -32,17 +30,25 @@ module Tapioca
|
|
|
32
30
|
|
|
33
31
|
private
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
#: (String line) -> bool
|
|
34
|
+
def rbs_comment?(line)
|
|
35
|
+
line.strip.start_with?(": ", "| ")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @override
|
|
39
|
+
#: (ConstNodeAdded event) -> void
|
|
36
40
|
def on_const(event)
|
|
37
41
|
event.node.comments = documentation_comments(event.symbol)
|
|
38
42
|
end
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
# @override
|
|
45
|
+
#: (ScopeNodeAdded event) -> void
|
|
41
46
|
def on_scope(event)
|
|
42
47
|
event.node.comments = documentation_comments(event.symbol)
|
|
43
48
|
end
|
|
44
49
|
|
|
45
|
-
|
|
50
|
+
# @override
|
|
51
|
+
#: (MethodNodeAdded event) -> void
|
|
46
52
|
def on_method(event)
|
|
47
53
|
separator = event.constant.singleton_class? ? "." : "#"
|
|
48
54
|
event.node.comments = documentation_comments(
|
|
@@ -51,7 +57,7 @@ module Tapioca
|
|
|
51
57
|
)
|
|
52
58
|
end
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
#: (String name, ?sigs: Array[RBI::Sig]) -> Array[RBI::Comment]
|
|
55
61
|
def documentation_comments(name, sigs: [])
|
|
56
62
|
yard_docs = YARD::Registry.at(name)
|
|
57
63
|
return [] unless yard_docs
|
|
@@ -60,7 +66,7 @@ module Tapioca
|
|
|
60
66
|
return [] if /(copyright|license)/i.match?(docstring)
|
|
61
67
|
|
|
62
68
|
comments = docstring.lines
|
|
63
|
-
.reject { |line| IGNORED_COMMENTS.any? { |comment| line.include?(comment) } }
|
|
69
|
+
.reject { |line| IGNORED_COMMENTS.any? { |comment| line.include?(comment) } || rbs_comment?(line) }
|
|
64
70
|
.map! { |line| RBI::Comment.new(line) }
|
|
65
71
|
|
|
66
72
|
tags = yard_docs.tags
|
|
@@ -95,7 +101,8 @@ module Tapioca
|
|
|
95
101
|
comments
|
|
96
102
|
end
|
|
97
103
|
|
|
98
|
-
|
|
104
|
+
# @override
|
|
105
|
+
#: (NodeAdded event) -> bool
|
|
99
106
|
def ignore?(event)
|
|
100
107
|
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
|
|
101
108
|
end
|