tapioca 0.15.0 → 0.16.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.
- checksums.yaml +4 -4
- data/lib/tapioca/dsl/compiler.rb +2 -2
- data/lib/tapioca/dsl/compilers/aasm.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +1 -3
- data/lib/tapioca/dsl/compilers/active_record_associations.rb +13 -0
- data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_relations.rb +219 -207
- data/lib/tapioca/dsl/compilers/active_support_concern.rb +7 -8
- data/lib/tapioca/dsl/compilers/active_support_time_ext.rb +68 -0
- 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 +1 -1
- data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +1 -1
- data/lib/tapioca/dsl/compilers/protobuf.rb +1 -3
- data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +1 -1
- data/lib/tapioca/dsl/compilers/smart_properties.rb +3 -2
- data/lib/tapioca/dsl/compilers/state_machines.rb +3 -3
- data/lib/tapioca/dsl/compilers/url_helpers.rb +25 -13
- data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +23 -9
- data/lib/tapioca/helpers/test/dsl_compiler.rb +1 -0
- data/lib/tapioca/internal.rb +6 -6
- data/lib/tapioca/loaders/dsl.rb +7 -0
- data/lib/tapioca/loaders/loader.rb +15 -4
- data/lib/tapioca/rbi_ext/model.rb +15 -42
- data/lib/tapioca/runtime/reflection.rb +1 -1
- data/lib/tapioca/version.rb +1 -1
- data/lib/tapioca.rb +2 -0
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a448cd511151879e4eef761b28cc8f5b1904f0d57e560a38af09bdda9689f98
|
4
|
+
data.tar.gz: 563c5e68f866444da629a4b206fed22b8a27531c36c0378d669886aa2a704eaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c847afeb5c173ad8b0c46a0f2fd214336150124fd96f0c729029ce492a5f4aea4bf5d26adfd64cf386486f22342b21f502cdbc52c68ca544a65c4bf6777dacee
|
7
|
+
data.tar.gz: e25a62343cc4522d37e9508b4215f6efb9115b93e1e9ba38c71edf26da025126732b4762b834304d0e439c741d581f238e29e22dded9fcbf0415256041f8f849
|
data/lib/tapioca/dsl/compiler.rb
CHANGED
@@ -49,7 +49,7 @@ module Tapioca
|
|
49
49
|
sig { returns(T::Enumerable[T::Class[T.anything]]) }
|
50
50
|
def all_classes
|
51
51
|
@all_classes ||= T.let(
|
52
|
-
|
52
|
+
ObjectSpace.each_object(Class),
|
53
53
|
T.nilable(T::Enumerable[T::Class[T.anything]]),
|
54
54
|
)
|
55
55
|
end
|
@@ -57,7 +57,7 @@ module Tapioca
|
|
57
57
|
sig { returns(T::Enumerable[Module]) }
|
58
58
|
def all_modules
|
59
59
|
@all_modules ||= T.let(
|
60
|
-
|
60
|
+
ObjectSpace.each_object(Module),
|
61
61
|
T.nilable(T::Enumerable[Module]),
|
62
62
|
)
|
63
63
|
end
|
@@ -147,7 +147,7 @@ module Tapioca
|
|
147
147
|
machine.create_method(
|
148
148
|
method,
|
149
149
|
parameters: [
|
150
|
-
|
150
|
+
create_rest_param("callbacks", type: "T.any(String, Symbol, T::Class[T.anything], Proc)"),
|
151
151
|
create_block_param("block", type: "T.nilable(T.proc.bind(#{constant_name}).void)"),
|
152
152
|
],
|
153
153
|
)
|
@@ -57,9 +57,7 @@ module Tapioca
|
|
57
57
|
sig { override.returns(T::Enumerable[Module]) }
|
58
58
|
def gather_constants
|
59
59
|
# Collect all the classes that include ActiveModel::Validations
|
60
|
-
all_classes.select
|
61
|
-
c < ActiveModel::Validations
|
62
|
-
end
|
60
|
+
all_classes.select { |c| ActiveModel::Validations > c }
|
63
61
|
end
|
64
62
|
end
|
65
63
|
|
@@ -188,6 +188,7 @@ module Tapioca
|
|
188
188
|
def populate_single_assoc_getter_setter(klass, association_name, reflection)
|
189
189
|
association_class = type_for(reflection)
|
190
190
|
association_type = as_nilable_type(association_class)
|
191
|
+
association_methods_module = constant.generated_association_methods
|
191
192
|
|
192
193
|
klass.create_method(
|
193
194
|
association_name.to_s,
|
@@ -206,6 +207,18 @@ module Tapioca
|
|
206
207
|
"reset_#{association_name}",
|
207
208
|
return_type: "void",
|
208
209
|
)
|
210
|
+
if association_methods_module.method_defined?("#{association_name}_changed?")
|
211
|
+
klass.create_method(
|
212
|
+
"#{association_name}_changed?",
|
213
|
+
return_type: "T::Boolean",
|
214
|
+
)
|
215
|
+
end
|
216
|
+
if association_methods_module.method_defined?("#{association_name}_previously_changed?")
|
217
|
+
klass.create_method(
|
218
|
+
"#{association_name}_previously_changed?",
|
219
|
+
return_type: "T::Boolean",
|
220
|
+
)
|
221
|
+
end
|
209
222
|
unless reflection.polymorphic?
|
210
223
|
klass.create_method(
|
211
224
|
"build_#{association_name}",
|
@@ -111,7 +111,7 @@ module Tapioca
|
|
111
111
|
sig { params(mod: RBI::Scope, name: String).void }
|
112
112
|
def create_fixture_method(mod, name)
|
113
113
|
return_type = return_type_for_fixture(name)
|
114
|
-
mod
|
114
|
+
mod.create_method(name) do |node|
|
115
115
|
node.add_opt_param("fixture_name", "nil")
|
116
116
|
node.add_rest_param("other_fixtures")
|
117
117
|
|
@@ -155,6 +155,25 @@ module Tapioca
|
|
155
155
|
|
156
156
|
ConstantType = type_member { { fixed: T.class_of(::ActiveRecord::Base) } }
|
157
157
|
|
158
|
+
# From ActiveRecord::ConnectionAdapter::Quoting#quote, minus nil
|
159
|
+
ID_TYPES = T.let(
|
160
|
+
[
|
161
|
+
"String",
|
162
|
+
"Symbol",
|
163
|
+
"::ActiveSupport::Multibyte::Chars",
|
164
|
+
"T::Boolean",
|
165
|
+
"BigDecimal",
|
166
|
+
"Numeric",
|
167
|
+
"::ActiveRecord::Type::Binary::Data",
|
168
|
+
"::ActiveRecord::Type::Time::Value",
|
169
|
+
"Date",
|
170
|
+
"Time",
|
171
|
+
"::ActiveSupport::Duration",
|
172
|
+
"T::Class[T.anything]",
|
173
|
+
].to_set.freeze,
|
174
|
+
T::Set[String],
|
175
|
+
)
|
176
|
+
|
158
177
|
sig { override.void }
|
159
178
|
def decorate
|
160
179
|
create_classes_and_includes
|
@@ -220,7 +239,7 @@ module Tapioca
|
|
220
239
|
[:find_or_create_by, :find_or_create_by!, :find_or_initialize_by, :create_or_find_by, :create_or_find_by!],
|
221
240
|
T::Array[Symbol],
|
222
241
|
)
|
223
|
-
BUILDER_METHODS = T.let([:new, :
|
242
|
+
BUILDER_METHODS = T.let([:new, :create, :create!, :build], T::Array[Symbol])
|
224
243
|
TO_ARRAY_METHODS = T.let([:to_ary, :to_a], T::Array[Symbol])
|
225
244
|
|
226
245
|
private
|
@@ -663,58 +682,43 @@ module Tapioca
|
|
663
682
|
return_type: "T::Boolean",
|
664
683
|
)
|
665
684
|
when :find
|
666
|
-
|
667
|
-
id_types = [
|
668
|
-
"String",
|
669
|
-
"Symbol",
|
670
|
-
"::ActiveSupport::Multibyte::Chars",
|
671
|
-
"T::Boolean",
|
672
|
-
"BigDecimal",
|
673
|
-
"Numeric",
|
674
|
-
"::ActiveRecord::Type::Binary::Data",
|
675
|
-
"::ActiveRecord::Type::Time::Value",
|
676
|
-
"Date",
|
677
|
-
"Time",
|
678
|
-
"::ActiveSupport::Duration",
|
679
|
-
"T::Class[T.anything]",
|
680
|
-
].to_set
|
685
|
+
id_types = ID_TYPES
|
681
686
|
|
682
687
|
if constant.table_exists?
|
683
688
|
primary_key_type = constant.type_for_attribute(constant.primary_key)
|
684
689
|
type = Tapioca::Dsl::Helpers::ActiveModelTypeHelper.type_for(primary_key_type)
|
685
690
|
type = RBIHelper.as_non_nilable_type(type)
|
686
|
-
|
691
|
+
|
692
|
+
id_types = ID_TYPES.union([type]) if type != "T.untyped"
|
687
693
|
end
|
688
694
|
|
689
695
|
id_types = "T.any(#{id_types.to_a.join(", ")})"
|
696
|
+
if constant.try(:composite_primary_key?)
|
697
|
+
id_types = "T::Array[#{id_types}]"
|
698
|
+
end
|
690
699
|
|
691
|
-
array_type =
|
692
|
-
|
693
|
-
|
694
|
-
"
|
700
|
+
array_type = "T::Array[#{id_types}]"
|
701
|
+
|
702
|
+
common_relation_methods_module.create_method("find") do |method|
|
703
|
+
method.add_opt_param("args", "nil")
|
704
|
+
method.add_block_param("block")
|
705
|
+
|
706
|
+
method.add_sig do |sig|
|
707
|
+
sig.add_param("args", id_types)
|
708
|
+
sig.return_type = constant_name
|
709
|
+
end
|
710
|
+
|
711
|
+
method.add_sig do |sig|
|
712
|
+
sig.add_param("args", array_type)
|
713
|
+
sig.return_type = "T::Enumerable[#{constant_name}]"
|
714
|
+
end
|
715
|
+
|
716
|
+
method.add_sig do |sig|
|
717
|
+
sig.add_param("args", "NilClass")
|
718
|
+
sig.add_param("block", "T.proc.params(object: #{constant_name}).void")
|
719
|
+
sig.return_type = as_nilable_type(constant_name)
|
720
|
+
end
|
695
721
|
end
|
696
|
-
sigs = [
|
697
|
-
common_relation_methods_module.create_sig(
|
698
|
-
parameters: { args: id_types },
|
699
|
-
return_type: constant_name,
|
700
|
-
),
|
701
|
-
common_relation_methods_module.create_sig(
|
702
|
-
parameters: { args: array_type },
|
703
|
-
return_type: "T::Enumerable[#{constant_name}]",
|
704
|
-
),
|
705
|
-
common_relation_methods_module.create_sig(
|
706
|
-
parameters: {
|
707
|
-
args: "NilClass",
|
708
|
-
block: "T.proc.params(object: #{constant_name}).void",
|
709
|
-
},
|
710
|
-
return_type: as_nilable_type(constant_name),
|
711
|
-
),
|
712
|
-
]
|
713
|
-
common_relation_methods_module.create_method_with_sigs(
|
714
|
-
"find",
|
715
|
-
sigs: sigs,
|
716
|
-
parameters: [RBI::OptParam.new("args", "nil"), RBI::BlockParam.new("block")],
|
717
|
-
)
|
718
722
|
when :find_by
|
719
723
|
create_common_method(
|
720
724
|
"find_by",
|
@@ -747,21 +751,18 @@ module Tapioca
|
|
747
751
|
return_type: constant_name,
|
748
752
|
)
|
749
753
|
when :first, :last, :take
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
sigs: sigs,
|
763
|
-
parameters: [RBI::OptParam.new("limit", "nil")],
|
764
|
-
)
|
754
|
+
common_relation_methods_module.create_method(method_name.to_s) do |method|
|
755
|
+
method.add_opt_param("limit", "nil")
|
756
|
+
|
757
|
+
method.add_sig do |sig|
|
758
|
+
sig.return_type = as_nilable_type(constant_name)
|
759
|
+
end
|
760
|
+
|
761
|
+
method.add_sig do |sig|
|
762
|
+
sig.add_param("limit", "Integer")
|
763
|
+
sig.return_type = "T::Array[#{constant_name}]"
|
764
|
+
end
|
765
|
+
end
|
765
766
|
when :raise_record_not_found_exception!
|
766
767
|
# skip
|
767
768
|
else
|
@@ -821,24 +822,21 @@ module Tapioca
|
|
821
822
|
return_type: "T.any(Integer, Float, BigDecimal)",
|
822
823
|
)
|
823
824
|
when :count
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
RBI::BlockParam.new("block"),
|
840
|
-
],
|
841
|
-
)
|
825
|
+
common_relation_methods_module.create_method(method_name.to_s) do |method|
|
826
|
+
method.add_opt_param("column_name", "nil")
|
827
|
+
method.add_block_param("block")
|
828
|
+
|
829
|
+
method.add_sig do |sig|
|
830
|
+
sig.add_param("column_name", "T.nilable(T.any(String, Symbol))")
|
831
|
+
sig.return_type = "Integer"
|
832
|
+
end
|
833
|
+
|
834
|
+
method.add_sig do |sig|
|
835
|
+
sig.add_param("column_name", "NilClass")
|
836
|
+
sig.add_param("block", "T.proc.params(object: #{constant_name}).void")
|
837
|
+
sig.return_type = "Integer"
|
838
|
+
end
|
839
|
+
end
|
842
840
|
when :ids
|
843
841
|
create_common_method("ids", return_type: "Array")
|
844
842
|
when :pick, :pluck
|
@@ -850,29 +848,21 @@ module Tapioca
|
|
850
848
|
return_type: "T.untyped",
|
851
849
|
)
|
852
850
|
when :sum
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
}
|
865
|
-
return_type
|
866
|
-
|
867
|
-
|
868
|
-
common_relation_methods_module.create_method_with_sigs(
|
869
|
-
method_name.to_s,
|
870
|
-
sigs: sigs,
|
871
|
-
parameters: [
|
872
|
-
RBI::OptParam.new("initial_value_or_column", "nil"),
|
873
|
-
RBI::BlockParam.new("block"),
|
874
|
-
],
|
875
|
-
)
|
851
|
+
common_relation_methods_module.create_method(method_name.to_s) do |method|
|
852
|
+
method.add_opt_param("initial_value_or_column", "nil")
|
853
|
+
method.add_block_param("block")
|
854
|
+
|
855
|
+
method.add_sig do |sig|
|
856
|
+
sig.add_param("initial_value_or_column", "T.untyped")
|
857
|
+
sig.return_type = "T.any(Integer, Float, BigDecimal)"
|
858
|
+
end
|
859
|
+
|
860
|
+
method.add_sig(type_params: ["U"]) do |sig|
|
861
|
+
sig.add_param("initial_value_or_column", "T.nilable(T.type_parameter(:U))")
|
862
|
+
sig.add_param("block", "T.proc.params(object: #{constant_name}).returns(T.type_parameter(:U))")
|
863
|
+
sig.return_type = "T.type_parameter(:U)"
|
864
|
+
end
|
865
|
+
end
|
876
866
|
end
|
877
867
|
end
|
878
868
|
|
@@ -880,102 +870,100 @@ module Tapioca
|
|
880
870
|
case method_name
|
881
871
|
when :find_each
|
882
872
|
order = ActiveRecord::Batches.instance_method(:find_each).parameters.include?([:key, :order])
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
)
|
873
|
+
|
874
|
+
common_relation_methods_module.create_method("find_each") do |method|
|
875
|
+
method.add_kw_opt_param("start", "nil")
|
876
|
+
method.add_kw_opt_param("finish", "nil")
|
877
|
+
method.add_kw_opt_param("batch_size", "1000")
|
878
|
+
method.add_kw_opt_param("error_on_ignore", "nil")
|
879
|
+
method.add_kw_opt_param("order", ":asc") if order
|
880
|
+
method.add_block_param("block")
|
881
|
+
|
882
|
+
method.add_sig do |sig|
|
883
|
+
sig.add_param("start", "T.untyped")
|
884
|
+
sig.add_param("finish", "T.untyped")
|
885
|
+
sig.add_param("batch_size", "Integer")
|
886
|
+
sig.add_param("error_on_ignore", "T.untyped")
|
887
|
+
sig.add_param("order", "Symbol") if order
|
888
|
+
sig.add_param("block", "T.proc.params(object: #{constant_name}).void")
|
889
|
+
sig.return_type = "void"
|
890
|
+
end
|
891
|
+
|
892
|
+
method.add_sig do |sig|
|
893
|
+
sig.add_param("start", "T.untyped")
|
894
|
+
sig.add_param("finish", "T.untyped")
|
895
|
+
sig.add_param("batch_size", "Integer")
|
896
|
+
sig.add_param("error_on_ignore", "T.untyped")
|
897
|
+
sig.add_param("order", "Symbol") if order
|
898
|
+
sig.return_type = "T::Enumerator[#{constant_name}]"
|
899
|
+
end
|
900
|
+
end
|
912
901
|
when :find_in_batches
|
913
902
|
order = ActiveRecord::Batches.instance_method(:find_in_batches).parameters.include?([:key, :order])
|
914
|
-
|
915
|
-
start
|
916
|
-
finish
|
917
|
-
batch_size
|
918
|
-
error_on_ignore
|
919
|
-
order
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
],
|
942
|
-
)
|
903
|
+
common_relation_methods_module.create_method("find_in_batches") do |method|
|
904
|
+
method.add_kw_opt_param("start", "nil")
|
905
|
+
method.add_kw_opt_param("finish", "nil")
|
906
|
+
method.add_kw_opt_param("batch_size", "1000")
|
907
|
+
method.add_kw_opt_param("error_on_ignore", "nil")
|
908
|
+
method.add_kw_opt_param("order", ":asc") if order
|
909
|
+
method.add_block_param("block")
|
910
|
+
|
911
|
+
method.add_sig do |sig|
|
912
|
+
sig.add_param("start", "T.untyped")
|
913
|
+
sig.add_param("finish", "T.untyped")
|
914
|
+
sig.add_param("batch_size", "Integer")
|
915
|
+
sig.add_param("error_on_ignore", "T.untyped")
|
916
|
+
sig.add_param("order", "Symbol") if order
|
917
|
+
sig.add_param("block", "T.proc.params(object: T::Array[#{constant_name}]).void")
|
918
|
+
sig.return_type = "void"
|
919
|
+
end
|
920
|
+
|
921
|
+
method.add_sig do |sig|
|
922
|
+
sig.add_param("start", "T.untyped")
|
923
|
+
sig.add_param("finish", "T.untyped")
|
924
|
+
sig.add_param("batch_size", "Integer")
|
925
|
+
sig.add_param("error_on_ignore", "T.untyped")
|
926
|
+
sig.add_param("order", "Symbol") if order
|
927
|
+
sig.return_type = "T::Enumerator[T::Enumerator[#{constant_name}]]"
|
928
|
+
end
|
929
|
+
end
|
943
930
|
when :in_batches
|
944
931
|
order = ActiveRecord::Batches.instance_method(:in_batches).parameters.include?([:key, :order])
|
945
932
|
use_ranges = ActiveRecord::Batches.instance_method(:in_batches).parameters.include?([:key, :use_ranges])
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
933
|
+
|
934
|
+
common_relation_methods_module.create_method("in_batches") do |method|
|
935
|
+
method.add_kw_opt_param("of", "1000")
|
936
|
+
method.add_kw_opt_param("start", "nil")
|
937
|
+
method.add_kw_opt_param("finish", "nil")
|
938
|
+
method.add_kw_opt_param("load", "false")
|
939
|
+
method.add_kw_opt_param("error_on_ignore", "nil")
|
940
|
+
method.add_kw_opt_param("order", ":asc") if order
|
941
|
+
method.add_kw_opt_param("use_ranges", "nil") if use_ranges
|
942
|
+
method.add_block_param("block")
|
943
|
+
|
944
|
+
method.add_sig do |sig|
|
945
|
+
sig.add_param("of", "Integer")
|
946
|
+
sig.add_param("start", "T.untyped")
|
947
|
+
sig.add_param("finish", "T.untyped")
|
948
|
+
sig.add_param("load", "T.untyped")
|
949
|
+
sig.add_param("error_on_ignore", "T.untyped")
|
950
|
+
sig.add_param("order", "Symbol") if order
|
951
|
+
sig.add_param("use_ranges", "T.untyped") if use_ranges
|
952
|
+
sig.add_param("block", "T.proc.params(object: #{RelationClassName}).void")
|
953
|
+
sig.return_type = "void"
|
954
|
+
end
|
955
|
+
|
956
|
+
method.add_sig do |sig|
|
957
|
+
sig.add_param("of", "Integer")
|
958
|
+
sig.add_param("start", "T.untyped")
|
959
|
+
sig.add_param("finish", "T.untyped")
|
960
|
+
sig.add_param("load", "T.untyped")
|
961
|
+
sig.add_param("error_on_ignore", "T.untyped")
|
962
|
+
sig.add_param("order", "Symbol") if order
|
963
|
+
sig.add_param("use_ranges", "T.untyped") if use_ranges
|
964
|
+
sig.return_type = "::ActiveRecord::Batches::BatchEnumerator"
|
965
|
+
end
|
966
|
+
end
|
979
967
|
end
|
980
968
|
end
|
981
969
|
|
@@ -991,26 +979,50 @@ module Tapioca
|
|
991
979
|
end
|
992
980
|
|
993
981
|
FIND_OR_CREATE_METHODS.each do |method_name|
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
982
|
+
common_relation_methods_module.create_method(method_name.to_s) do |method|
|
983
|
+
method.add_param("attributes")
|
984
|
+
method.add_block_param("block")
|
985
|
+
|
986
|
+
# `T.untyped` matches `T::Array[T.untyped]` so the array signature
|
987
|
+
# must be defined first for Sorbet to pick it, if valid.
|
988
|
+
method.add_sig do |sig|
|
989
|
+
sig.add_param("attributes", "T::Array[T.untyped]")
|
990
|
+
sig.add_param("block", "T.nilable(T.proc.params(object: #{constant_name}).void)")
|
991
|
+
sig.return_type = "T::Array[#{constant_name}]"
|
992
|
+
end
|
993
|
+
|
994
|
+
method.add_sig do |sig|
|
995
|
+
sig.add_param("attributes", "T.untyped")
|
996
|
+
sig.add_param("block", "T.nilable(T.proc.params(object: #{constant_name}).void)")
|
997
|
+
sig.return_type = constant_name
|
998
|
+
end
|
999
|
+
end
|
1003
1000
|
end
|
1004
1001
|
|
1005
1002
|
BUILDER_METHODS.each do |method_name|
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1003
|
+
common_relation_methods_module.create_method(method_name.to_s) do |method|
|
1004
|
+
method.add_opt_param("attributes", "nil")
|
1005
|
+
method.add_block_param("block")
|
1006
|
+
|
1007
|
+
method.add_sig do |sig|
|
1008
|
+
sig.add_param("block", "T.nilable(T.proc.params(object: #{constant_name}).void)")
|
1009
|
+
sig.return_type = constant_name
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
# `T.untyped` matches `T::Array[T.untyped]` so the array signature
|
1013
|
+
# must be defined first for Sorbet to pick it, if valid.
|
1014
|
+
method.add_sig do |sig|
|
1015
|
+
sig.add_param("attributes", "T::Array[T.untyped]")
|
1016
|
+
sig.add_param("block", "T.nilable(T.proc.params(object: #{constant_name}).void)")
|
1017
|
+
sig.return_type = "T::Array[#{constant_name}]"
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
method.add_sig do |sig|
|
1021
|
+
sig.add_param("attributes", "T.untyped")
|
1022
|
+
sig.add_param("block", "T.nilable(T.proc.params(object: #{constant_name}).void)")
|
1023
|
+
sig.return_type = constant_name
|
1024
|
+
end
|
1025
|
+
end
|
1014
1026
|
end
|
1015
1027
|
end
|
1016
1028
|
|
@@ -66,19 +66,18 @@ module Tapioca
|
|
66
66
|
|
67
67
|
sig { override.returns(T::Enumerable[Module]) }
|
68
68
|
def gather_constants
|
69
|
-
# Find all Modules that are:
|
70
69
|
all_modules.select do |mod|
|
71
|
-
#
|
72
|
-
name_of(mod) &&
|
73
|
-
# not singleton classes
|
70
|
+
name_of(mod) && # i.e. not anonymous
|
74
71
|
!mod.singleton_class? &&
|
75
|
-
|
76
|
-
mod
|
77
|
-
# have dependencies (i.e. include another concern)
|
78
|
-
!dependencies_of(mod).empty?
|
72
|
+
ActiveSupport::Concern > mod.singleton_class &&
|
73
|
+
has_dependencies?(mod)
|
79
74
|
end
|
80
75
|
end
|
81
76
|
|
77
|
+
# Returns true when `mod` includes other concerns
|
78
|
+
sig { params(mod: Module).returns(T::Boolean) }
|
79
|
+
def has_dependencies?(mod) = dependencies_of(mod).any?
|
80
|
+
|
82
81
|
sig { params(concern: Module).returns(T::Array[Module]) }
|
83
82
|
def dependencies_of(concern)
|
84
83
|
concern.instance_variable_get(:@_dependencies) || []
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
return unless defined?(Time.current) && defined?(ActiveSupport::TimeWithZone)
|
5
|
+
|
6
|
+
module Tapioca
|
7
|
+
module Dsl
|
8
|
+
module Compilers
|
9
|
+
# `Tapioca::Dsl::Compilers::ActiveSupportTimeExt` generates an RBI file for the `Time#current` method
|
10
|
+
# defined by [Active Support's Time extensions](https://api.rubyonrails.org/classes/Time.html).
|
11
|
+
#
|
12
|
+
# If `Time.zone` or `config.time_zone` are set, then the `Time.current` method will be defined as returning
|
13
|
+
# an instance of `ActiveSupport::TimeWithZone`, otherwise it will return an instance of `Time`.
|
14
|
+
#
|
15
|
+
# For an application that is configured with:
|
16
|
+
# ```ruby
|
17
|
+
# config.time_zone = "UTC"
|
18
|
+
# ```
|
19
|
+
# this compiler will produce the following RBI file:
|
20
|
+
# ```rbi
|
21
|
+
# class Time
|
22
|
+
# class << self
|
23
|
+
# sig { returns(::ActiveSupport::TimeWithZone) }
|
24
|
+
# def current; end
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# ```
|
28
|
+
# whereas if `Time.zone` and `config.time_zone` are not set, it will produce:
|
29
|
+
# ```rbi
|
30
|
+
# class Time
|
31
|
+
# class << self
|
32
|
+
# sig { returns(::Time) }
|
33
|
+
# def current; end
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
# ```
|
37
|
+
class ActiveSupportTimeExt < Compiler
|
38
|
+
extend T::Sig
|
39
|
+
|
40
|
+
ConstantType = type_member { { fixed: T.class_of(::Time) } }
|
41
|
+
|
42
|
+
sig { override.void }
|
43
|
+
def decorate
|
44
|
+
return unless constant.respond_to?(:zone)
|
45
|
+
|
46
|
+
root.create_path(constant) do |mod|
|
47
|
+
return_type = if ::Time.zone
|
48
|
+
"::ActiveSupport::TimeWithZone"
|
49
|
+
else
|
50
|
+
"::Time"
|
51
|
+
end
|
52
|
+
|
53
|
+
mod.create_method("current", return_type: return_type, class_method: true)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class << self
|
58
|
+
extend T::Sig
|
59
|
+
|
60
|
+
sig { override.returns(T::Enumerable[Module]) }
|
61
|
+
def gather_constants
|
62
|
+
[::Time]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -80,7 +80,7 @@ module Tapioca
|
|
80
80
|
|
81
81
|
sig { override.returns(T::Enumerable[Module]) }
|
82
82
|
def gather_constants
|
83
|
-
all_classes.select { |c|
|
83
|
+
all_classes.select { |c| GraphQL::Schema::Mutation > c && GraphQL::Schema::RelayClassicMutation != c }
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -100,7 +100,7 @@ module Tapioca
|
|
100
100
|
sig { override.returns(T::Enumerable[Module]) }
|
101
101
|
def gather_constants
|
102
102
|
descendants_of(::ActiveRecord::Base).select do |klass|
|
103
|
-
|
103
|
+
::IdentityCache::WithoutPrimaryIndex > klass
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
@@ -159,9 +159,7 @@ module Tapioca
|
|
159
159
|
def gather_constants
|
160
160
|
marker = Google::Protobuf::MessageExts::ClassMethods
|
161
161
|
|
162
|
-
enum_modules = ObjectSpace.each_object(Google::Protobuf::EnumDescriptor).map
|
163
|
-
T.cast(desc, Google::Protobuf::EnumDescriptor).enummodule
|
164
|
-
end
|
162
|
+
enum_modules = ObjectSpace.each_object(Google::Protobuf::EnumDescriptor).map(&:enummodule)
|
165
163
|
|
166
164
|
results = if Google::Protobuf.const_defined?(:AbstractMessage)
|
167
165
|
abstract_message_const = ::Google::Protobuf.const_get(:AbstractMessage)
|
@@ -86,8 +86,9 @@ module Tapioca
|
|
86
86
|
def gather_constants
|
87
87
|
all_modules.select do |c|
|
88
88
|
name_of(c) &&
|
89
|
-
|
90
|
-
|
89
|
+
::SmartProperties > c &&
|
90
|
+
::SmartProperties::Validations::Ancestor != c &&
|
91
|
+
::SmartProperties::ClassMethods === c
|
91
92
|
end
|
92
93
|
end
|
93
94
|
end
|
@@ -159,7 +159,7 @@ module Tapioca
|
|
159
159
|
|
160
160
|
sig { override.returns(T::Enumerable[Module]) }
|
161
161
|
def gather_constants
|
162
|
-
all_classes.select { |mod|
|
162
|
+
all_classes.select { |mod| ::StateMachines::InstanceMethods > mod }
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
@@ -231,12 +231,12 @@ module Tapioca
|
|
231
231
|
instance_module.create_method(
|
232
232
|
attribute,
|
233
233
|
return_type: state_type,
|
234
|
-
)
|
234
|
+
) if ::StateMachines::HelperModule === machine.owner_class.instance_method(attribute).owner
|
235
235
|
instance_module.create_method(
|
236
236
|
"#{attribute}=",
|
237
237
|
parameters: [create_param("value", type: state_type)],
|
238
238
|
return_type: state_type,
|
239
|
-
)
|
239
|
+
) if ::StateMachines::HelperModule === machine.owner_class.instance_method("#{attribute}=").owner
|
240
240
|
end
|
241
241
|
|
242
242
|
sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
|
@@ -106,19 +106,28 @@ module Tapioca
|
|
106
106
|
routes_reloader = Rails.application.routes_reloader
|
107
107
|
routes_reloader.execute_unless_loaded if routes_reloader&.respond_to?(:execute_unless_loaded)
|
108
108
|
|
109
|
-
|
110
|
-
|
109
|
+
url_helpers_module = Rails.application.routes.named_routes.url_helpers_module
|
110
|
+
path_helpers_module = Rails.application.routes.named_routes.path_helpers_module
|
111
|
+
|
112
|
+
Object.const_set(:GeneratedUrlHelpersModule, url_helpers_module)
|
113
|
+
Object.const_set(:GeneratedPathHelpersModule, path_helpers_module)
|
111
114
|
|
112
115
|
constants = all_modules.select do |mod|
|
113
116
|
next unless name_of(mod)
|
114
117
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
118
|
+
# Fast-path to quickly disqualify most cases
|
119
|
+
next false unless url_helpers_module > mod || # rubocop:disable Style/InvertibleUnlessCondition
|
120
|
+
path_helpers_module > mod ||
|
121
|
+
url_helpers_module > mod.singleton_class ||
|
122
|
+
path_helpers_module > mod.singleton_class
|
123
|
+
|
124
|
+
includes_helper?(mod, url_helpers_module) ||
|
125
|
+
includes_helper?(mod, path_helpers_module) ||
|
126
|
+
includes_helper?(mod.singleton_class, url_helpers_module) ||
|
127
|
+
includes_helper?(mod.singleton_class, path_helpers_module)
|
119
128
|
end
|
120
129
|
|
121
|
-
constants.concat(NON_DISCOVERABLE_INCLUDERS)
|
130
|
+
constants.concat(NON_DISCOVERABLE_INCLUDERS).push(GeneratedUrlHelpersModule, GeneratedPathHelpersModule)
|
122
131
|
end
|
123
132
|
|
124
133
|
sig { returns(T::Array[Module]) }
|
@@ -134,17 +143,20 @@ module Tapioca
|
|
134
143
|
end.freeze
|
135
144
|
end
|
136
145
|
|
146
|
+
# Returns `true` if `mod` "directly" includes `helper`.
|
147
|
+
# For classes, this method will return false if the `helper` is included only by a superclass
|
137
148
|
sig { params(mod: Module, helper: Module).returns(T::Boolean) }
|
138
149
|
private def includes_helper?(mod, helper)
|
139
|
-
|
150
|
+
ancestors = ancestors_of(mod)
|
140
151
|
|
141
|
-
if Class === mod
|
142
|
-
|
143
|
-
|
152
|
+
own_ancestors = if Class === mod && (superclass = superclass_of(mod))
|
153
|
+
# These ancestors are unique to `mod`, and exclude those in common with `superclass`.
|
154
|
+
ancestors.take(ancestors.count - ancestors_of(superclass).size)
|
155
|
+
else
|
156
|
+
ancestors
|
144
157
|
end
|
145
158
|
|
146
|
-
|
147
|
-
ancestors.any? { |ancestor| helper == ancestor }
|
159
|
+
own_ancestors.include?(helper)
|
148
160
|
end
|
149
161
|
end
|
150
162
|
|
@@ -104,7 +104,7 @@ module Tapioca
|
|
104
104
|
|
105
105
|
column = @constant.columns_hash[column_name]
|
106
106
|
column_type = @constant.attribute_types[column_name]
|
107
|
-
getter_type = type_for_activerecord_value(column_type)
|
107
|
+
getter_type = type_for_activerecord_value(column_type, column_nullability: !!column&.null)
|
108
108
|
setter_type =
|
109
109
|
case column_type
|
110
110
|
when ActiveRecord::Enum::EnumType
|
@@ -121,8 +121,8 @@ module Tapioca
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
-
sig { params(column_type: T.untyped).returns(String) }
|
125
|
-
def type_for_activerecord_value(column_type)
|
124
|
+
sig { params(column_type: T.untyped, column_nullability: T::Boolean).returns(String) }
|
125
|
+
def type_for_activerecord_value(column_type, column_nullability:)
|
126
126
|
case column_type
|
127
127
|
when ->(type) { defined?(MoneyColumn) && MoneyColumn::ActiveRecordType === type }
|
128
128
|
"::Money"
|
@@ -133,11 +133,12 @@ module Tapioca
|
|
133
133
|
}
|
134
134
|
# Reflect to see if `ActiveModel::Type::Value` is being used first.
|
135
135
|
getter_type = Tapioca::Dsl::Helpers::ActiveModelTypeHelper.type_for(column_type)
|
136
|
-
return getter_type unless getter_type == "T.untyped"
|
137
136
|
|
138
|
-
#
|
137
|
+
# Fallback to String as `ActiveRecord::Encryption::EncryptedAttributeType` inherits from
|
139
138
|
# `ActiveRecord::Type::Text` which inherits from `ActiveModel::Type::String`.
|
140
|
-
"::String"
|
139
|
+
return "::String" if getter_type == "T.untyped"
|
140
|
+
|
141
|
+
as_non_nilable_if_persisted_and_not_nullable(getter_type, column_nullability:)
|
141
142
|
when ActiveRecord::Type::String
|
142
143
|
"::String"
|
143
144
|
when ActiveRecord::Type::Date
|
@@ -160,7 +161,7 @@ module Tapioca
|
|
160
161
|
defined?(ActiveRecord::Normalization::NormalizedValueType) &&
|
161
162
|
ActiveRecord::Normalization::NormalizedValueType === type
|
162
163
|
}
|
163
|
-
type_for_activerecord_value(column_type.cast_type)
|
164
|
+
type_for_activerecord_value(column_type.cast_type, column_nullability:)
|
164
165
|
when ->(type) {
|
165
166
|
defined?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Uuid) &&
|
166
167
|
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Uuid === type
|
@@ -180,12 +181,25 @@ module Tapioca
|
|
180
181
|
defined?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array) &&
|
181
182
|
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array === type
|
182
183
|
}
|
183
|
-
"T::Array[#{type_for_activerecord_value(column_type.subtype)}]"
|
184
|
+
"T::Array[#{type_for_activerecord_value(column_type.subtype, column_nullability:)}]"
|
184
185
|
else
|
185
|
-
|
186
|
+
as_non_nilable_if_persisted_and_not_nullable(
|
187
|
+
ActiveModelTypeHelper.type_for(column_type),
|
188
|
+
column_nullability: column_nullability,
|
189
|
+
)
|
186
190
|
end
|
187
191
|
end
|
188
192
|
|
193
|
+
sig { params(base_type: String, column_nullability: T::Boolean).returns(String) }
|
194
|
+
def as_non_nilable_if_persisted_and_not_nullable(base_type, column_nullability:)
|
195
|
+
# It's possible that when ActiveModel::Type::Value is used, the signature being reflected on in
|
196
|
+
# ActiveModelTypeHelper.type_for(type_value) may say the type can be nilable. However, if the type is
|
197
|
+
# persisted and the column is not nullable, we can assume it's not nilable.
|
198
|
+
return as_non_nilable_type(base_type) if @column_type_option.persisted? && !column_nullability
|
199
|
+
|
200
|
+
base_type
|
201
|
+
end
|
202
|
+
|
189
203
|
sig { params(column_type: ActiveRecord::Enum::EnumType).returns(String) }
|
190
204
|
def enum_setter_type(column_type)
|
191
205
|
# In Rails < 7 this method is private. When support for that is dropped we can call the method directly
|
data/lib/tapioca/internal.rb
CHANGED
@@ -19,24 +19,24 @@ require "netrc"
|
|
19
19
|
require "parallel"
|
20
20
|
require "pathname"
|
21
21
|
require "shellwords"
|
22
|
-
require "spoom"
|
23
22
|
require "tempfile"
|
24
23
|
require "thor"
|
25
24
|
require "yaml"
|
26
25
|
require "yard-sorbet"
|
27
26
|
|
28
27
|
require "tapioca/runtime/dynamic_mixin_compiler"
|
29
|
-
require "tapioca/helpers/gem_helper"
|
30
|
-
|
31
|
-
require "tapioca/helpers/git_attributes"
|
32
|
-
require "tapioca/helpers/sorbet_helper"
|
33
|
-
require "tapioca/helpers/rbi_helper"
|
34
28
|
require "tapioca/sorbet_ext/backcompat_patches"
|
35
29
|
require "tapioca/sorbet_ext/name_patch"
|
36
30
|
require "tapioca/sorbet_ext/generic_name_patch"
|
37
31
|
require "tapioca/sorbet_ext/proc_bind_patch"
|
38
32
|
require "tapioca/runtime/generic_type_registry"
|
39
33
|
|
34
|
+
require "spoom"
|
35
|
+
require "tapioca/helpers/gem_helper"
|
36
|
+
require "tapioca/helpers/git_attributes"
|
37
|
+
require "tapioca/helpers/sorbet_helper"
|
38
|
+
require "tapioca/helpers/rbi_helper"
|
39
|
+
|
40
40
|
require "tapioca/helpers/source_uri"
|
41
41
|
require "tapioca/helpers/cli_helper"
|
42
42
|
require "tapioca/helpers/config_helper"
|
data/lib/tapioca/loaders/dsl.rb
CHANGED
@@ -63,10 +63,17 @@ module Tapioca
|
|
63
63
|
def load_dsl_compilers
|
64
64
|
say("Loading DSL compiler classes... ")
|
65
65
|
|
66
|
+
# Load all built-in compilers
|
67
|
+
Dir.glob("#{Tapioca::LIB_ROOT_DIR}/tapioca/dsl/compilers/*.rb").each do |compiler|
|
68
|
+
require File.expand_path(compiler)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Load all custom compilers exported from gems
|
66
72
|
::Gem.find_files("tapioca/dsl/compilers/*.rb").each do |compiler|
|
67
73
|
require File.expand_path(compiler)
|
68
74
|
end
|
69
75
|
|
76
|
+
# Load all custom compilers from the project
|
70
77
|
Dir.glob([
|
71
78
|
"#{@tapioca_path}/generators/**/*.rb", # TODO: Here for backcompat, remove later
|
72
79
|
"#{@tapioca_path}/compilers/**/*.rb",
|
@@ -47,12 +47,23 @@ module Tapioca
|
|
47
47
|
).void
|
48
48
|
end
|
49
49
|
def load_rails_application(environment_load: false, eager_load: false, app_root: ".", halt_upon_load_error: true)
|
50
|
-
return unless File.exist?("
|
50
|
+
return unless File.exist?(File.expand_path("config/application.rb", app_root))
|
51
51
|
|
52
|
-
if environment_load
|
53
|
-
|
52
|
+
load_path = if environment_load
|
53
|
+
"config/environment"
|
54
54
|
else
|
55
|
-
|
55
|
+
"config/application"
|
56
|
+
end
|
57
|
+
|
58
|
+
require File.expand_path(load_path, app_root)
|
59
|
+
|
60
|
+
unless defined?(Rails)
|
61
|
+
say(
|
62
|
+
"\nTried to load the app from `#{load_path}` as a Rails application " \
|
63
|
+
"but the `Rails` constant wasn't defined after loading the file.",
|
64
|
+
:yellow,
|
65
|
+
)
|
66
|
+
return
|
56
67
|
end
|
57
68
|
|
58
69
|
eager_load_rails_app if eager_load
|
@@ -80,65 +80,38 @@ module RBI
|
|
80
80
|
params(
|
81
81
|
name: String,
|
82
82
|
parameters: T::Array[TypedParam],
|
83
|
-
return_type: String,
|
83
|
+
return_type: T.nilable(String),
|
84
84
|
class_method: T::Boolean,
|
85
85
|
visibility: RBI::Visibility,
|
86
86
|
comments: T::Array[RBI::Comment],
|
87
|
+
block: T.nilable(T.proc.params(node: RBI::Method).void),
|
87
88
|
).void
|
88
89
|
end
|
89
|
-
def create_method(name, parameters: [], return_type:
|
90
|
-
comments: [])
|
91
|
-
sig_params = parameters.to_h { |param| [param.param.name, param.type] }
|
92
|
-
sig = create_sig(parameters: sig_params, return_type: return_type)
|
93
|
-
create_method_with_sigs(
|
94
|
-
name,
|
95
|
-
sigs: [sig],
|
96
|
-
parameters: parameters.map(&:param),
|
97
|
-
class_method: class_method,
|
98
|
-
visibility: visibility,
|
99
|
-
comments: comments,
|
100
|
-
)
|
101
|
-
end
|
102
|
-
|
103
|
-
sig do
|
104
|
-
params(
|
105
|
-
name: String,
|
106
|
-
sigs: T::Array[RBI::Sig],
|
107
|
-
parameters: T::Array[RBI::Param],
|
108
|
-
class_method: T::Boolean,
|
109
|
-
visibility: RBI::Visibility,
|
110
|
-
comments: T::Array[RBI::Comment],
|
111
|
-
).void
|
112
|
-
end
|
113
|
-
def create_method_with_sigs(name, sigs:, parameters: [], class_method: false, visibility: RBI::Public.new,
|
114
|
-
comments: [])
|
90
|
+
def create_method(name, parameters: [], return_type: nil, class_method: false, visibility: RBI::Public.new,
|
91
|
+
comments: [], &block)
|
115
92
|
return unless Tapioca::RBIHelper.valid_method_name?(name)
|
116
93
|
|
94
|
+
sigs = []
|
95
|
+
|
96
|
+
if !block || !parameters.empty? || return_type
|
97
|
+
# If there is no block, and the params and return type have not been supplied, then
|
98
|
+
# we create a single signature with the given parameters and return type
|
99
|
+
params = parameters.map { |param| RBI::SigParam.new(param.param.name.to_s, param.type) }
|
100
|
+
sigs << RBI::Sig.new(params: params, return_type: return_type || "T.untyped")
|
101
|
+
end
|
102
|
+
|
117
103
|
method = RBI::Method.new(
|
118
104
|
name,
|
119
105
|
sigs: sigs,
|
120
|
-
params: parameters,
|
106
|
+
params: parameters.map(&:param),
|
121
107
|
is_singleton: class_method,
|
122
108
|
visibility: visibility,
|
123
109
|
comments: comments,
|
110
|
+
&block
|
124
111
|
)
|
125
112
|
self << method
|
126
113
|
end
|
127
114
|
|
128
|
-
sig do
|
129
|
-
params(
|
130
|
-
parameters: T::Hash[T.any(String, Symbol), String],
|
131
|
-
type_parameters: T::Array[String],
|
132
|
-
return_type: String,
|
133
|
-
).returns(RBI::Sig)
|
134
|
-
end
|
135
|
-
def create_sig(parameters:, type_parameters: [], return_type: "T.untyped")
|
136
|
-
params = parameters.map do |name, type|
|
137
|
-
RBI::SigParam.new(name.to_s, type)
|
138
|
-
end
|
139
|
-
RBI::Sig.new(type_params: type_parameters, params: params, return_type: return_type)
|
140
|
-
end
|
141
|
-
|
142
115
|
private
|
143
116
|
|
144
117
|
sig { returns(T::Hash[String, RBI::Node]) }
|
@@ -166,7 +166,7 @@ module Tapioca
|
|
166
166
|
end
|
167
167
|
def descendants_of(klass)
|
168
168
|
result = ObjectSpace.each_object(klass.singleton_class).reject do |k|
|
169
|
-
|
169
|
+
k.singleton_class? || k == klass
|
170
170
|
end
|
171
171
|
|
172
172
|
T.unsafe(result)
|
data/lib/tapioca/version.rb
CHANGED
data/lib/tapioca.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "sorbet-runtime"
|
5
|
+
require "rubygems/user_interaction"
|
5
6
|
|
6
7
|
module Tapioca
|
7
8
|
extend T::Sig
|
@@ -29,6 +30,7 @@ module Tapioca
|
|
29
30
|
|
30
31
|
class Error < StandardError; end
|
31
32
|
|
33
|
+
LIB_ROOT_DIR = T.let(T.must(__dir__), String)
|
32
34
|
SORBET_DIR = T.let("sorbet", String)
|
33
35
|
SORBET_CONFIG_FILE = T.let("#{SORBET_DIR}/config", String)
|
34
36
|
TAPIOCA_DIR = T.let("#{SORBET_DIR}/tapioca", String)
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tapioca
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ufuk Kayserilioglu
|
8
8
|
- Alan Wu
|
9
9
|
- Alexandre Terrasa
|
10
10
|
- Peter Zhu
|
11
|
-
autorequire:
|
11
|
+
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2024-06
|
14
|
+
date: 2024-08-06 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -61,7 +61,7 @@ dependencies:
|
|
61
61
|
requirements:
|
62
62
|
- - ">="
|
63
63
|
- !ruby/object:Gem::Version
|
64
|
-
version: 0.1.
|
64
|
+
version: 0.1.14
|
65
65
|
- - "<"
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: '0.2'
|
@@ -71,7 +71,7 @@ dependencies:
|
|
71
71
|
requirements:
|
72
72
|
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: 0.1.
|
74
|
+
version: 0.1.14
|
75
75
|
- - "<"
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0.2'
|
@@ -131,7 +131,7 @@ dependencies:
|
|
131
131
|
- - ">="
|
132
132
|
- !ruby/object:Gem::Version
|
133
133
|
version: '0'
|
134
|
-
description:
|
134
|
+
description:
|
135
135
|
email:
|
136
136
|
- ruby@shopify.com
|
137
137
|
executables:
|
@@ -186,6 +186,7 @@ files:
|
|
186
186
|
- lib/tapioca/dsl/compilers/active_storage.rb
|
187
187
|
- lib/tapioca/dsl/compilers/active_support_concern.rb
|
188
188
|
- lib/tapioca/dsl/compilers/active_support_current_attributes.rb
|
189
|
+
- lib/tapioca/dsl/compilers/active_support_time_ext.rb
|
189
190
|
- lib/tapioca/dsl/compilers/config.rb
|
190
191
|
- lib/tapioca/dsl/compilers/frozen_record.rb
|
191
192
|
- lib/tapioca/dsl/compilers/graphql_input_object.rb
|
@@ -274,7 +275,7 @@ licenses:
|
|
274
275
|
- MIT
|
275
276
|
metadata:
|
276
277
|
allowed_push_host: https://rubygems.org
|
277
|
-
post_install_message:
|
278
|
+
post_install_message:
|
278
279
|
rdoc_options: []
|
279
280
|
require_paths:
|
280
281
|
- lib
|
@@ -289,8 +290,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
289
290
|
- !ruby/object:Gem::Version
|
290
291
|
version: '0'
|
291
292
|
requirements: []
|
292
|
-
rubygems_version: 3.5.
|
293
|
-
signing_key:
|
293
|
+
rubygems_version: 3.5.16
|
294
|
+
signing_key:
|
294
295
|
specification_version: 4
|
295
296
|
summary: A Ruby Interface file generator for gems, core types and the Ruby standard
|
296
297
|
library
|