tapioca 0.18.0 → 0.19.1
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 +2 -2
- data/lib/tapioca/cli.rb +1 -1
- data/lib/tapioca/commands/abstract_dsl.rb +1 -1
- data/lib/tapioca/commands/check_shims.rb +3 -0
- data/lib/tapioca/commands/configure.rb +1 -0
- data/lib/tapioca/commands/todo.rb +8 -2
- data/lib/tapioca/dsl/compiler.rb +18 -13
- data/lib/tapioca/dsl/compilers/aasm.rb +5 -2
- data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +2 -2
- data/lib/tapioca/dsl/compilers/action_mailer.rb +1 -1
- data/lib/tapioca/dsl/compilers/action_text.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_job.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_model_attributes.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_associations.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_columns.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_enum.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_relations.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_scope.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_store.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_resource.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_storage.rb +2 -2
- data/lib/tapioca/dsl/compilers/active_support_concern.rb +6 -6
- data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_support_environment_inquirer.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_support_time_ext.rb +1 -1
- data/lib/tapioca/dsl/compilers/config.rb +2 -2
- data/lib/tapioca/dsl/compilers/frozen_record.rb +1 -1
- data/lib/tapioca/dsl/compilers/graphql_input_object.rb +1 -1
- data/lib/tapioca/dsl/compilers/graphql_mutation.rb +1 -1
- data/lib/tapioca/dsl/compilers/identity_cache.rb +2 -2
- data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +1 -1
- data/lib/tapioca/dsl/compilers/kredis.rb +1 -1
- data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +2 -2
- data/lib/tapioca/dsl/compilers/protobuf.rb +1 -1
- data/lib/tapioca/dsl/compilers/rails_generators.rb +1 -1
- data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +1 -1
- data/lib/tapioca/dsl/compilers/smart_properties.rb +1 -1
- data/lib/tapioca/dsl/compilers/state_machines.rb +2 -2
- data/lib/tapioca/dsl/compilers/url_helpers.rb +7 -7
- data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +1 -1
- data/lib/tapioca/dsl/pipeline.rb +10 -10
- data/lib/tapioca/gem/events.rb +7 -7
- data/lib/tapioca/gem/listeners/documentation.rb +94 -0
- data/lib/tapioca/gem/listeners/methods.rb +8 -8
- data/lib/tapioca/gem/listeners/mixins.rb +3 -3
- data/lib/tapioca/gem/listeners/sorbet_signatures.rb +5 -7
- data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +1 -1
- data/lib/tapioca/gem/listeners.rb +1 -1
- data/lib/tapioca/gem/pipeline.rb +20 -19
- data/lib/tapioca/gemfile.rb +0 -16
- data/lib/tapioca/helpers/rbi_helper.rb +7 -0
- data/lib/tapioca/helpers/sorbet_helper.rb +19 -0
- data/lib/tapioca/helpers/test/dsl_compiler.rb +2 -9
- data/lib/tapioca/internal.rb +2 -1
- data/lib/tapioca/rbi_ext/model.rb +6 -2
- data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +6 -6
- data/lib/tapioca/runtime/generic_type_registry.rb +8 -8
- data/lib/tapioca/runtime/reflection.rb +28 -21
- data/lib/tapioca/runtime/trackers/constant_definition.rb +3 -3
- data/lib/tapioca/runtime/trackers/method_definition.rb +4 -4
- data/lib/tapioca/runtime/trackers/mixin.rb +5 -5
- data/lib/tapioca/runtime/trackers/required_ancestor.rb +2 -2
- data/lib/tapioca/runtime/trackers/tracker.rb +1 -1
- data/lib/tapioca/sorbet_ext/generic_name_patch.rb +1 -1
- data/lib/tapioca/sorbet_ext/void_patch.rb +29 -0
- data/lib/tapioca/static/symbol_loader.rb +32 -6
- data/lib/tapioca/version.rb +1 -1
- metadata +13 -12
- data/lib/tapioca/gem/listeners/yard_doc.rb +0 -110
|
@@ -94,21 +94,14 @@ module Tapioca
|
|
|
94
94
|
compiler.decorate
|
|
95
95
|
|
|
96
96
|
rbi = Tapioca::DEFAULT_RBI_FORMATTER.print_file(file)
|
|
97
|
-
result = sorbet(
|
|
98
|
-
"--no-config",
|
|
99
|
-
"--stop-after",
|
|
100
|
-
"parser",
|
|
101
|
-
"-e",
|
|
102
|
-
"\"#{rbi}\"",
|
|
103
|
-
)
|
|
104
97
|
|
|
105
|
-
|
|
98
|
+
sorbet_syntax_check!(rbi, rbi_mode: true) do |stderr|
|
|
106
99
|
raise(SyntaxError, <<~MSG)
|
|
107
100
|
Expected generated RBI file for `#{constant_name}` to not have any parsing errors.
|
|
108
101
|
|
|
109
102
|
Got these parsing errors:
|
|
110
103
|
|
|
111
|
-
#{
|
|
104
|
+
#{stderr}
|
|
112
105
|
MSG
|
|
113
106
|
end
|
|
114
107
|
|
data/lib/tapioca/internal.rb
CHANGED
|
@@ -13,6 +13,7 @@ require "tapioca/sorbet_ext/backcompat_patches"
|
|
|
13
13
|
require "tapioca/sorbet_ext/name_patch"
|
|
14
14
|
require "tapioca/sorbet_ext/generic_name_patch"
|
|
15
15
|
require "tapioca/sorbet_ext/proc_bind_patch"
|
|
16
|
+
require "tapioca/sorbet_ext/void_patch"
|
|
16
17
|
require "tapioca/runtime/generic_type_registry"
|
|
17
18
|
|
|
18
19
|
# The rewriter needs to be loaded very early so RBS comments within Tapioca itself are rewritten
|
|
@@ -41,7 +42,7 @@ require "shellwords"
|
|
|
41
42
|
require "tempfile"
|
|
42
43
|
require "thor"
|
|
43
44
|
require "yaml"
|
|
44
|
-
require "
|
|
45
|
+
require "rubydex"
|
|
45
46
|
require "prism"
|
|
46
47
|
|
|
47
48
|
require "tapioca/helpers/gem_helper"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
module RBI
|
|
5
5
|
class Tree
|
|
6
|
-
#: (
|
|
6
|
+
#: (Module[top] constant) ?{ (Scope scope) -> void } -> Scope
|
|
7
7
|
def create_path(constant, &block)
|
|
8
8
|
constant_name = Tapioca::Runtime::Reflection.name_of(constant)
|
|
9
9
|
raise "given constant does not have a name" unless constant_name
|
|
@@ -77,7 +77,11 @@ module RBI
|
|
|
77
77
|
# If there is no block, and the params and return type have not been supplied, then
|
|
78
78
|
# we create a single signature with the given parameters and return type
|
|
79
79
|
params = parameters.map { |param| RBI::SigParam.new(param.param.name.to_s, param.type) }
|
|
80
|
-
|
|
80
|
+
return_type ||= "T.untyped"
|
|
81
|
+
type_params = Tapioca::RBIHelper.extract_type_parameters(parameters.map(&:type).append(return_type))
|
|
82
|
+
|
|
83
|
+
sig = RBI::Sig.new(params: params, return_type: return_type, type_params: type_params)
|
|
84
|
+
sigs << sig
|
|
81
85
|
end
|
|
82
86
|
|
|
83
87
|
method = RBI::Method.new(
|
|
@@ -6,7 +6,7 @@ module Tapioca
|
|
|
6
6
|
class DynamicMixinCompiler
|
|
7
7
|
include Runtime::Reflection
|
|
8
8
|
|
|
9
|
-
#: Array[
|
|
9
|
+
#: Array[Module[top]]
|
|
10
10
|
attr_reader :dynamic_extends, :dynamic_includes
|
|
11
11
|
|
|
12
12
|
#: Array[Symbol]
|
|
@@ -15,7 +15,7 @@ module Tapioca
|
|
|
15
15
|
#: Array[Symbol]
|
|
16
16
|
attr_reader :instance_attribute_readers, :instance_attribute_writers, :instance_attribute_predicates
|
|
17
17
|
|
|
18
|
-
#: (
|
|
18
|
+
#: (Module[top] constant) -> void
|
|
19
19
|
def initialize(constant)
|
|
20
20
|
@constant = constant
|
|
21
21
|
mixins_from_modules = {}.compare_by_identity
|
|
@@ -109,12 +109,12 @@ module Tapioca
|
|
|
109
109
|
# is the list of all dynamically extended modules because of that
|
|
110
110
|
# constant. We grab that value by deleting the key for the original
|
|
111
111
|
# constant.
|
|
112
|
-
@dynamic_extends = mixins_from_modules.delete(constant) || [] #: Array[
|
|
112
|
+
@dynamic_extends = mixins_from_modules.delete(constant) || [] #: Array[Module[top]]
|
|
113
113
|
|
|
114
114
|
# Since we deleted the original constant from the list of keys, all
|
|
115
115
|
# the keys that remain are the ones that are dynamically included modules
|
|
116
116
|
# during the include of the original constant.
|
|
117
|
-
@dynamic_includes = mixins_from_modules.keys #: Array[
|
|
117
|
+
@dynamic_includes = mixins_from_modules.keys #: Array[Module[top]]
|
|
118
118
|
|
|
119
119
|
@class_attribute_readers = class_attribute_readers #: Array[Symbol]
|
|
120
120
|
@class_attribute_writers = class_attribute_writers #: Array[Symbol]
|
|
@@ -173,7 +173,7 @@ module Tapioca
|
|
|
173
173
|
tree << RBI::Include.new("GeneratedInstanceMethods")
|
|
174
174
|
end
|
|
175
175
|
|
|
176
|
-
#: (RBI::Tree tree) -> [Array[
|
|
176
|
+
#: (RBI::Tree tree) -> [Array[Module[top]], Array[Module[top]]]
|
|
177
177
|
def compile_mixes_in_class_methods(tree)
|
|
178
178
|
includes = dynamic_includes.filter_map do |mod|
|
|
179
179
|
qname = qualified_name_of(mod)
|
|
@@ -208,7 +208,7 @@ module Tapioca
|
|
|
208
208
|
[[], []] # silence errors
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
-
#: (
|
|
211
|
+
#: (Module[top] mod, Array[Module[top]] dynamic_extends) -> bool
|
|
212
212
|
def module_included_by_another_dynamic_extend?(mod, dynamic_extends)
|
|
213
213
|
dynamic_extends.any? do |dynamic_extend|
|
|
214
214
|
mod != dynamic_extend && ancestors_of(dynamic_extend).include?(mod)
|
|
@@ -21,16 +21,16 @@ module Tapioca
|
|
|
21
21
|
# variable to type variable serializers. This allows us to associate type variables
|
|
22
22
|
# to the constant names that represent them, easily.
|
|
23
23
|
module GenericTypeRegistry
|
|
24
|
-
@generic_instances = {} #: Hash[String,
|
|
24
|
+
@generic_instances = {} #: Hash[String, Module[top]]
|
|
25
25
|
|
|
26
|
-
@type_variables = {}.compare_by_identity #: Hash[
|
|
26
|
+
@type_variables = {}.compare_by_identity #: Hash[Module[top], Array[TypeVariableModule]]
|
|
27
27
|
|
|
28
28
|
class GenericType < T::Types::Simple
|
|
29
|
-
#: (
|
|
29
|
+
#: (Module[top] raw_type, Module[top] underlying_type) -> void
|
|
30
30
|
def initialize(raw_type, underlying_type)
|
|
31
31
|
super(raw_type)
|
|
32
32
|
|
|
33
|
-
@underlying_type = underlying_type #:
|
|
33
|
+
@underlying_type = underlying_type #: Module[top]
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# @override
|
|
@@ -52,7 +52,7 @@ module Tapioca
|
|
|
52
52
|
# 2 hash lookups (for the other two `Foo[Integer]`s).
|
|
53
53
|
#
|
|
54
54
|
# This method returns the created or cached clone of the constant.
|
|
55
|
-
#: (untyped constant, untyped types) ->
|
|
55
|
+
#: (untyped constant, untyped types) -> Module[top]
|
|
56
56
|
def register_type(constant, types)
|
|
57
57
|
# Build the name of the instantiated generic type,
|
|
58
58
|
# something like `"Foo[X, Y, Z]"`
|
|
@@ -72,7 +72,7 @@ module Tapioca
|
|
|
72
72
|
@generic_instances.values.any? { |generic_type| generic_type === instance }
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
#: (
|
|
75
|
+
#: (Module[top] constant) -> Array[TypeVariableModule]?
|
|
76
76
|
def lookup_type_variables(constant)
|
|
77
77
|
@type_variables[constant]
|
|
78
78
|
end
|
|
@@ -95,7 +95,7 @@ module Tapioca
|
|
|
95
95
|
|
|
96
96
|
private
|
|
97
97
|
|
|
98
|
-
#: (
|
|
98
|
+
#: (Module[top] constant, String name) -> Module[top]
|
|
99
99
|
def create_generic_type(constant, name)
|
|
100
100
|
generic_type = case constant
|
|
101
101
|
when Class
|
|
@@ -164,7 +164,7 @@ module Tapioca
|
|
|
164
164
|
end
|
|
165
165
|
end
|
|
166
166
|
|
|
167
|
-
#: (
|
|
167
|
+
#: (Module[top] constant) -> Array[TypeVariableModule]
|
|
168
168
|
def lookup_or_initialize_type_variables(constant)
|
|
169
169
|
@type_variables[constant] ||= []
|
|
170
170
|
end
|
|
@@ -20,7 +20,7 @@ module Tapioca
|
|
|
20
20
|
PROTECTED_INSTANCE_METHODS_METHOD = Module.instance_method(:protected_instance_methods) #: UnboundMethod
|
|
21
21
|
PRIVATE_INSTANCE_METHODS_METHOD = Module.instance_method(:private_instance_methods) #: UnboundMethod
|
|
22
22
|
METHOD_METHOD = Kernel.instance_method(:method) #: UnboundMethod
|
|
23
|
-
UNDEFINED_CONSTANT = Module.new.freeze #:
|
|
23
|
+
UNDEFINED_CONSTANT = Module.new.freeze #: Module[top]
|
|
24
24
|
|
|
25
25
|
REQUIRED_FROM_LABELS = ["<top (required)>", "<main>", "<compiled>"].freeze #: Array[String]
|
|
26
26
|
|
|
@@ -31,7 +31,7 @@ module Tapioca
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# @without_runtime
|
|
34
|
-
#: (String symbol, ?inherit: bool, ?namespace:
|
|
34
|
+
#: (String symbol, ?inherit: bool, ?namespace: Module[top]) -> BasicObject
|
|
35
35
|
def constantize(symbol, inherit: false, namespace: Object)
|
|
36
36
|
namespace.const_get(symbol, inherit)
|
|
37
37
|
rescue NameError, LoadError, RuntimeError, ArgumentError, TypeError
|
|
@@ -43,23 +43,23 @@ module Tapioca
|
|
|
43
43
|
CLASS_METHOD.bind_call(object)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
#: (
|
|
46
|
+
#: (Module[top] constant) -> Array[Symbol]
|
|
47
47
|
def constants_of(constant)
|
|
48
48
|
CONSTANTS_METHOD.bind_call(constant, false)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
#: (
|
|
51
|
+
#: (Module[top] constant) -> String?
|
|
52
52
|
def name_of(constant)
|
|
53
53
|
name = NAME_METHOD.bind_call(constant)
|
|
54
54
|
name&.start_with?("#<") ? nil : name
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
#: (
|
|
57
|
+
#: (Module[top] constant) -> Class[top]
|
|
58
58
|
def singleton_class_of(constant)
|
|
59
59
|
SINGLETON_CLASS_METHOD.bind_call(constant)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
#: (
|
|
62
|
+
#: (Module[top] constant) -> Array[Module[top]]
|
|
63
63
|
def ancestors_of(constant)
|
|
64
64
|
ANCESTORS_METHOD.bind_call(constant)
|
|
65
65
|
end
|
|
@@ -69,7 +69,7 @@ module Tapioca
|
|
|
69
69
|
SUPERCLASS_METHOD.bind_call(constant)
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
-
#: (Class[top] singleton_class) ->
|
|
72
|
+
#: (Class[top] singleton_class) -> Module[top]?
|
|
73
73
|
def attached_class_of(singleton_class)
|
|
74
74
|
result = singleton_class.attached_object
|
|
75
75
|
Module === result ? result : nil
|
|
@@ -85,22 +85,22 @@ module Tapioca
|
|
|
85
85
|
EQUAL_METHOD.bind_call(object, other)
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
-
#: (
|
|
88
|
+
#: (Module[top] constant) -> Array[Symbol]
|
|
89
89
|
def public_instance_methods_of(constant)
|
|
90
90
|
PUBLIC_INSTANCE_METHODS_METHOD.bind_call(constant)
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
#: (
|
|
93
|
+
#: (Module[top] constant) -> Array[Symbol]
|
|
94
94
|
def protected_instance_methods_of(constant)
|
|
95
95
|
PROTECTED_INSTANCE_METHODS_METHOD.bind_call(constant)
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
#: (
|
|
98
|
+
#: (Module[top] constant) -> Array[Symbol]
|
|
99
99
|
def private_instance_methods_of(constant)
|
|
100
100
|
PRIVATE_INSTANCE_METHODS_METHOD.bind_call(constant)
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
-
#: (
|
|
103
|
+
#: (Module[top] constant) -> Array[Module[top]]
|
|
104
104
|
def inherited_ancestors_of(constant)
|
|
105
105
|
if Class === constant
|
|
106
106
|
ancestors_of(superclass_of(constant) || Object)
|
|
@@ -109,7 +109,7 @@ module Tapioca
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
#: (
|
|
112
|
+
#: (Module[top] constant) -> String?
|
|
113
113
|
def qualified_name_of(constant)
|
|
114
114
|
name = name_of(constant)
|
|
115
115
|
return if name.nil?
|
|
@@ -142,7 +142,7 @@ module Tapioca
|
|
|
142
142
|
type.to_s
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
#: (
|
|
145
|
+
#: (Module[top] constant, Symbol method) -> Method
|
|
146
146
|
def method_of(constant, method)
|
|
147
147
|
METHOD_METHOD.bind_call(constant, method)
|
|
148
148
|
end
|
|
@@ -211,32 +211,39 @@ module Tapioca
|
|
|
211
211
|
SourceLocation.from_loc([file, resolved_loc.lineno])
|
|
212
212
|
end
|
|
213
213
|
|
|
214
|
-
#: (
|
|
214
|
+
#: (Module[top] constant) -> Set[String]
|
|
215
215
|
def file_candidates_for(constant)
|
|
216
|
-
|
|
216
|
+
# Grab all source files for (relevant) methods defined on the constant
|
|
217
|
+
candidates = relevant_methods_for(constant).filter_map do |method|
|
|
217
218
|
method.source_location&.first
|
|
218
219
|
end.to_set
|
|
220
|
+
|
|
221
|
+
# Add the source file for the constant definition itself, if available.
|
|
222
|
+
source_location_candidate = const_source_location(name_of(constant).to_s)&.file
|
|
223
|
+
candidates.add(source_location_candidate) if source_location_candidate
|
|
224
|
+
|
|
225
|
+
candidates
|
|
219
226
|
end
|
|
220
227
|
|
|
221
|
-
#: (
|
|
228
|
+
#: (Module[top] constant) -> untyped
|
|
222
229
|
def abstract_type_of(constant)
|
|
223
230
|
T::Private::Abstract::Data.get(constant, :abstract_type) ||
|
|
224
231
|
T::Private::Abstract::Data.get(singleton_class_of(constant), :abstract_type)
|
|
225
232
|
end
|
|
226
233
|
|
|
227
|
-
#: (
|
|
234
|
+
#: (Module[top] constant) -> bool
|
|
228
235
|
def final_module?(constant)
|
|
229
236
|
T::Private::Final.final_module?(constant)
|
|
230
237
|
end
|
|
231
238
|
|
|
232
|
-
#: (
|
|
239
|
+
#: (Module[top] constant) -> bool
|
|
233
240
|
def sealed_module?(constant)
|
|
234
241
|
T::Private::Sealed.sealed_module?(constant)
|
|
235
242
|
end
|
|
236
243
|
|
|
237
244
|
private
|
|
238
245
|
|
|
239
|
-
#: (
|
|
246
|
+
#: (Module[top] constant) -> Array[UnboundMethod]
|
|
240
247
|
def relevant_methods_for(constant)
|
|
241
248
|
methods = methods_for(constant).select(&:source_location)
|
|
242
249
|
.reject { |x| method_defined_by_forwardable_module?(x) }
|
|
@@ -252,7 +259,7 @@ module Tapioca
|
|
|
252
259
|
end
|
|
253
260
|
end
|
|
254
261
|
|
|
255
|
-
#: (
|
|
262
|
+
#: (Module[top] constant) -> Array[UnboundMethod]
|
|
256
263
|
def methods_for(constant)
|
|
257
264
|
modules = [constant, singleton_class_of(constant)]
|
|
258
265
|
method_list_methods = [
|
|
@@ -266,7 +273,7 @@ module Tapioca
|
|
|
266
273
|
end
|
|
267
274
|
end
|
|
268
275
|
|
|
269
|
-
#: (
|
|
276
|
+
#: (Module[top] parent, String name) -> Module[top]?
|
|
270
277
|
def child_module_for_parent_with_name(parent, name)
|
|
271
278
|
return if parent.autoload?(name)
|
|
272
279
|
|
|
@@ -12,7 +12,7 @@ module Tapioca
|
|
|
12
12
|
extend Tracker
|
|
13
13
|
extend Reflection
|
|
14
14
|
|
|
15
|
-
@class_files = {}.compare_by_identity #: Hash[
|
|
15
|
+
@class_files = {}.compare_by_identity #: Hash[Module[top], Set[SourceLocation]]
|
|
16
16
|
|
|
17
17
|
# Immediately activated upon load. Observes class/module definition.
|
|
18
18
|
@class_tracepoint = TracePoint.trace(:class) do |tp|
|
|
@@ -83,12 +83,12 @@ module Tapioca
|
|
|
83
83
|
# Returns the files in which this class or module was opened. Doesn't know
|
|
84
84
|
# about situations where the class was opened prior to +require+ing,
|
|
85
85
|
# or where metaprogramming was used via +eval+, etc.
|
|
86
|
-
#: (
|
|
86
|
+
#: (Module[top] klass) -> Set[String]
|
|
87
87
|
def files_for(klass)
|
|
88
88
|
locations_for(klass).map(&:file).to_set
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
#: (
|
|
91
|
+
#: (Module[top] klass) -> Set[SourceLocation]
|
|
92
92
|
def locations_for(klass)
|
|
93
93
|
@class_files.fetch(klass, Set.new)
|
|
94
94
|
end
|
|
@@ -7,10 +7,10 @@ module Tapioca
|
|
|
7
7
|
module MethodDefinition
|
|
8
8
|
extend Tracker
|
|
9
9
|
|
|
10
|
-
@method_definitions = {}.compare_by_identity #: Hash[
|
|
10
|
+
@method_definitions = {}.compare_by_identity #: Hash[Module[top], Hash[Symbol, Array[SourceLocation]]]
|
|
11
11
|
|
|
12
12
|
class << self
|
|
13
|
-
#: (Symbol method_name,
|
|
13
|
+
#: (Symbol method_name, Module[top] owner, Array[Thread::Backtrace::Location] locations) -> void
|
|
14
14
|
def register(method_name, owner, locations)
|
|
15
15
|
return unless enabled?
|
|
16
16
|
# If Sorbet runtime is redefining a method, it sets this to true.
|
|
@@ -24,7 +24,7 @@ module Tapioca
|
|
|
24
24
|
registrations_for(method_name, owner) << loc
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
#: (Symbol method_name,
|
|
27
|
+
#: (Symbol method_name, Module[top] owner) -> Array[SourceLocation]
|
|
28
28
|
def method_definitions_for(method_name, owner)
|
|
29
29
|
definitions = registrations_for(method_name, owner)
|
|
30
30
|
|
|
@@ -38,7 +38,7 @@ module Tapioca
|
|
|
38
38
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
|
-
#: (Symbol method_name,
|
|
41
|
+
#: (Symbol method_name, Module[top] owner) -> Array[SourceLocation]
|
|
42
42
|
def registrations_for(method_name, owner)
|
|
43
43
|
owner_lookup = (@method_definitions[owner] ||= {})
|
|
44
44
|
owner_lookup[method_name] ||= []
|
|
@@ -24,7 +24,7 @@ module Tapioca
|
|
|
24
24
|
with_disabled_tracker(&block)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
#: (
|
|
27
|
+
#: (Module[top] constant, Module[top] mixin, Type mixin_type) -> void
|
|
28
28
|
def register(constant, mixin, mixin_type)
|
|
29
29
|
return unless enabled?
|
|
30
30
|
|
|
@@ -46,19 +46,19 @@ module Tapioca
|
|
|
46
46
|
attached_class
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
#: (
|
|
49
|
+
#: (Module[top] mixin) -> Hash[Type, Hash[Module[top], String]]
|
|
50
50
|
def constants_with_mixin(mixin)
|
|
51
51
|
find_or_initialize_mixin_lookup(mixin)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
#: (
|
|
54
|
+
#: (Module[top] mixin, Type mixin_type, Module[top] constant) -> String?
|
|
55
55
|
def mixin_location(mixin, mixin_type, constant)
|
|
56
56
|
find_or_initialize_mixin_lookup(mixin).dig(mixin_type, constant)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
private
|
|
60
60
|
|
|
61
|
-
#: (
|
|
61
|
+
#: (Module[top] constant, Module[top] mixin, Type mixin_type, String location) -> void
|
|
62
62
|
def register_with_location(constant, mixin, mixin_type, location)
|
|
63
63
|
return unless @enabled
|
|
64
64
|
|
|
@@ -66,7 +66,7 @@ module Tapioca
|
|
|
66
66
|
constants.fetch(mixin_type).store(constant, location)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
#: (
|
|
69
|
+
#: (Module[top] mixin) -> Hash[Type, Hash[Module[top], String]]
|
|
70
70
|
def find_or_initialize_mixin_lookup(mixin)
|
|
71
71
|
@mixins_to_constants[mixin] ||= {
|
|
72
72
|
Type::Prepend => {}.compare_by_identity,
|
|
@@ -17,12 +17,12 @@ module Tapioca
|
|
|
17
17
|
ancestors << block
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
#: (
|
|
20
|
+
#: (Module[top] mod) -> Array[^-> void]
|
|
21
21
|
def required_ancestors_blocks_by(mod)
|
|
22
22
|
@required_ancestors_map[mod] || []
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
#: (
|
|
25
|
+
#: (Module[top] mod) -> Array[untyped]
|
|
26
26
|
def required_ancestors_by(mod)
|
|
27
27
|
blocks = required_ancestors_blocks_by(mod)
|
|
28
28
|
blocks.map do |block|
|
|
@@ -133,7 +133,7 @@ module Tapioca
|
|
|
133
133
|
#: Type
|
|
134
134
|
attr_reader :type
|
|
135
135
|
|
|
136
|
-
#: (
|
|
136
|
+
#: (Module[top] context, Type type, Symbol variance, (^-> Hash[Symbol, untyped])? bounds_proc) -> void
|
|
137
137
|
def initialize(context, type, variance, bounds_proc)
|
|
138
138
|
@context = context
|
|
139
139
|
@type = type
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# If Signature has `effective_return_type`, then `return_type` always returns the correct type.
|
|
5
|
+
# Ref: https://github.com/sorbet/sorbet/pull/10121
|
|
6
|
+
return if T::Private::Methods::Signature.method_defined?(:effective_return_type)
|
|
7
|
+
|
|
8
|
+
module T
|
|
9
|
+
module Private
|
|
10
|
+
module Methods
|
|
11
|
+
module DeclBuilderPatch
|
|
12
|
+
def void
|
|
13
|
+
super.tap do
|
|
14
|
+
@_real_returns_is_void = true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def finalize!
|
|
19
|
+
super.tap do
|
|
20
|
+
#: self as untyped
|
|
21
|
+
decl.returns = T::Private::Types::Void::Private::INSTANCE if @_real_returns_is_void
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
DeclBuilder.prepend(DeclBuilderPatch)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -18,6 +18,19 @@ module Tapioca
|
|
|
18
18
|
T.must(@payload_symbols)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
#: (Array[Pathname] paths) -> Rubydex::Graph
|
|
22
|
+
def graph_from_paths(paths)
|
|
23
|
+
graph = Rubydex::Graph.new
|
|
24
|
+
graph.index_all(paths.map(&:to_s))
|
|
25
|
+
graph.resolve
|
|
26
|
+
graph
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#: (Gemfile::GemSpec gem) -> Set[String]
|
|
30
|
+
def gem_symbols(gem)
|
|
31
|
+
symbols_from_paths(gem.files)
|
|
32
|
+
end
|
|
33
|
+
|
|
21
34
|
#: (Gemfile::GemSpec gem) -> Set[String]
|
|
22
35
|
def engine_symbols(gem)
|
|
23
36
|
gem_engine = engines.find do |engine|
|
|
@@ -43,11 +56,6 @@ module Tapioca
|
|
|
43
56
|
Set.new
|
|
44
57
|
end
|
|
45
58
|
|
|
46
|
-
#: (Gemfile::GemSpec gem) -> Set[String]
|
|
47
|
-
def gem_symbols(gem)
|
|
48
|
-
symbols_from_paths(gem.files)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
59
|
#: (Array[Pathname] paths) -> Set[String]
|
|
52
60
|
def symbols_from_paths(paths)
|
|
53
61
|
return Set.new if paths.empty?
|
|
@@ -79,7 +87,25 @@ module Tapioca
|
|
|
79
87
|
|
|
80
88
|
#: (String input, ?table_type: String) -> String
|
|
81
89
|
def symbol_table_json_from(input, table_type: "symbol-table-json")
|
|
82
|
-
|
|
90
|
+
supported_values = ["symbol-table-json", "symbol-table-full-json"]
|
|
91
|
+
unless supported_values.include?(table_type)
|
|
92
|
+
raise NotImplementedError, <<~MSG
|
|
93
|
+
Got an unsupported value for `table_type` (#{table_type.inspect}).
|
|
94
|
+
The only supported values are:
|
|
95
|
+
#{supported_values.map { |v| "- #{v}" }.join("\n")}
|
|
96
|
+
|
|
97
|
+
This is because we use `--stop-after=namer` as a performance optimization. Other print formats
|
|
98
|
+
may require running later stages of Sorbet's pipeline. Please adjust the `stop-after` accordingly.
|
|
99
|
+
MSG
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
sorbet(
|
|
103
|
+
"--no-config",
|
|
104
|
+
"--quiet",
|
|
105
|
+
"--print=#{table_type}",
|
|
106
|
+
"--stop-after=namer",
|
|
107
|
+
input,
|
|
108
|
+
).out
|
|
83
109
|
end
|
|
84
110
|
end
|
|
85
111
|
end
|
data/lib/tapioca/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.19.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ufuk Kayserilioglu
|
|
@@ -83,47 +83,47 @@ dependencies:
|
|
|
83
83
|
- !ruby/object:Gem::Version
|
|
84
84
|
version: 0.2.2
|
|
85
85
|
- !ruby/object:Gem::Dependency
|
|
86
|
-
name:
|
|
86
|
+
name: rubydex
|
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
|
88
88
|
requirements:
|
|
89
89
|
- - ">="
|
|
90
90
|
- !ruby/object:Gem::Version
|
|
91
|
-
version: 0.
|
|
91
|
+
version: 0.1.0.beta10
|
|
92
92
|
type: :runtime
|
|
93
93
|
prerelease: false
|
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
|
95
95
|
requirements:
|
|
96
96
|
- - ">="
|
|
97
97
|
- !ruby/object:Gem::Version
|
|
98
|
-
version: 0.
|
|
98
|
+
version: 0.1.0.beta10
|
|
99
99
|
- !ruby/object:Gem::Dependency
|
|
100
|
-
name:
|
|
100
|
+
name: sorbet-static-and-runtime
|
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
|
102
102
|
requirements:
|
|
103
103
|
- - ">="
|
|
104
104
|
- !ruby/object:Gem::Version
|
|
105
|
-
version:
|
|
105
|
+
version: 0.6.12698
|
|
106
106
|
type: :runtime
|
|
107
107
|
prerelease: false
|
|
108
108
|
version_requirements: !ruby/object:Gem::Requirement
|
|
109
109
|
requirements:
|
|
110
110
|
- - ">="
|
|
111
111
|
- !ruby/object:Gem::Version
|
|
112
|
-
version:
|
|
112
|
+
version: 0.6.12698
|
|
113
113
|
- !ruby/object:Gem::Dependency
|
|
114
|
-
name:
|
|
114
|
+
name: thor
|
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
|
116
116
|
requirements:
|
|
117
117
|
- - ">="
|
|
118
118
|
- !ruby/object:Gem::Version
|
|
119
|
-
version:
|
|
119
|
+
version: 1.2.0
|
|
120
120
|
type: :runtime
|
|
121
121
|
prerelease: false
|
|
122
122
|
version_requirements: !ruby/object:Gem::Requirement
|
|
123
123
|
requirements:
|
|
124
124
|
- - ">="
|
|
125
125
|
- !ruby/object:Gem::Version
|
|
126
|
-
version:
|
|
126
|
+
version: 1.2.0
|
|
127
127
|
- !ruby/object:Gem::Dependency
|
|
128
128
|
name: rbi
|
|
129
129
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -253,6 +253,7 @@ files:
|
|
|
253
253
|
- lib/tapioca/gem/events.rb
|
|
254
254
|
- lib/tapioca/gem/listeners.rb
|
|
255
255
|
- lib/tapioca/gem/listeners/base.rb
|
|
256
|
+
- lib/tapioca/gem/listeners/documentation.rb
|
|
256
257
|
- lib/tapioca/gem/listeners/dynamic_mixins.rb
|
|
257
258
|
- lib/tapioca/gem/listeners/foreign_constants.rb
|
|
258
259
|
- lib/tapioca/gem/listeners/methods.rb
|
|
@@ -266,7 +267,6 @@ files:
|
|
|
266
267
|
- lib/tapioca/gem/listeners/sorbet_type_variables.rb
|
|
267
268
|
- lib/tapioca/gem/listeners/source_location.rb
|
|
268
269
|
- lib/tapioca/gem/listeners/subconstants.rb
|
|
269
|
-
- lib/tapioca/gem/listeners/yard_doc.rb
|
|
270
270
|
- lib/tapioca/gem/pipeline.rb
|
|
271
271
|
- lib/tapioca/gem_info.rb
|
|
272
272
|
- lib/tapioca/gemfile.rb
|
|
@@ -307,6 +307,7 @@ files:
|
|
|
307
307
|
- lib/tapioca/sorbet_ext/generic_name_patch.rb
|
|
308
308
|
- lib/tapioca/sorbet_ext/name_patch.rb
|
|
309
309
|
- lib/tapioca/sorbet_ext/proc_bind_patch.rb
|
|
310
|
+
- lib/tapioca/sorbet_ext/void_patch.rb
|
|
310
311
|
- lib/tapioca/static/requires_compiler.rb
|
|
311
312
|
- lib/tapioca/static/symbol_loader.rb
|
|
312
313
|
- lib/tapioca/static/symbol_table_parser.rb
|
|
@@ -330,7 +331,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
330
331
|
- !ruby/object:Gem::Version
|
|
331
332
|
version: '0'
|
|
332
333
|
requirements: []
|
|
333
|
-
rubygems_version: 4.0.
|
|
334
|
+
rubygems_version: 4.0.6
|
|
334
335
|
specification_version: 4
|
|
335
336
|
summary: A Ruby Interface file generator for gems, core types and the Ruby standard
|
|
336
337
|
library
|