orthoses-rails 0.3.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +31 -39
  3. data/examples/rails/Rakefile +139 -68
  4. data/examples/rails/config/database.yml +8 -0
  5. data/examples/rails/config/storage.yml +3 -0
  6. data/examples/rails/gemfiles/Gemfile_6_0 +16 -0
  7. data/examples/rails/gemfiles/Gemfile_6_0.lock +172 -0
  8. data/examples/rails/gemfiles/Gemfile_6_1 +15 -0
  9. data/examples/rails/gemfiles/Gemfile_6_1.lock +173 -0
  10. data/examples/rails/gemfiles/Gemfile_7_0 +15 -0
  11. data/examples/rails/gemfiles/Gemfile_7_0.lock +172 -0
  12. data/examples/rails/tasks/active_job.rake +95 -0
  13. data/examples/rails/tasks/active_model.rake +46 -0
  14. data/examples/rails/tasks/active_record.rake +83 -0
  15. data/examples/rails/tasks/active_storage.rake +94 -0
  16. data/examples/rails/tasks/active_support.rake +92 -0
  17. data/lib/orthoses/active_model/has_secure_password.rb +4 -4
  18. data/lib/orthoses/active_model.rb +0 -1
  19. data/lib/orthoses/active_record/delegated_type.rb +50 -0
  20. data/lib/orthoses/active_record/enum.rb +77 -0
  21. data/lib/orthoses/active_record/scope.rb +63 -0
  22. data/lib/orthoses/active_record.rb +3 -1
  23. data/lib/orthoses/active_support/class_attribute.rb +12 -12
  24. data/lib/orthoses/active_support/configurable.rb +36 -0
  25. data/lib/orthoses/active_support/delegation.rb +14 -14
  26. data/lib/orthoses/active_support/mattr_accessor.rb +8 -8
  27. data/lib/orthoses/active_support/time_with_zone.rb +22 -9
  28. data/lib/orthoses/active_support.rb +1 -4
  29. data/lib/orthoses/rails/version.rb +1 -1
  30. data/lib/orthoses/rails.rb +0 -1
  31. data/orthoses-rails.gemspec +1 -1
  32. metadata +22 -89
  33. data/examples/rails/known_sig/action_cable/connection/test_cookie_jar.rbs +0 -2
  34. data/examples/rails/known_sig/action_controller/metal.rbs +0 -4
  35. data/examples/rails/known_sig/action_dispatch/cookies/cookie_jar.rbs +0 -3
  36. data/examples/rails/known_sig/action_dispatch/response.rbs +0 -4
  37. data/examples/rails/patch/drb/drb_undumped.rbs +0 -2
  38. data/examples/rails/patch/drb.rbs +0 -2
  39. data/examples/rails/patch/erubi/engine.rbs +0 -4
  40. data/examples/rails/patch/erubi.rbs +0 -2
  41. data/examples/rails/patch/minitest/kernel.rbs +0 -44
  42. data/examples/rails/patch/minitest/minitest/abstract_reporter.rbs +0 -49
  43. data/examples/rails/patch/minitest/minitest/assertion.rbs +0 -16
  44. data/examples/rails/patch/minitest/minitest/assertions.rbs +0 -545
  45. data/examples/rails/patch/minitest/minitest/backtrace_filter.rbs +0 -16
  46. data/examples/rails/patch/minitest/minitest/bench_spec.rbs +0 -101
  47. data/examples/rails/patch/minitest/minitest/benchmark.rbs +0 -258
  48. data/examples/rails/patch/minitest/minitest/composite_reporter.rbs +0 -25
  49. data/examples/rails/patch/minitest/minitest/expectations.rbs +0 -21
  50. data/examples/rails/patch/minitest/minitest/guard.rbs +0 -64
  51. data/examples/rails/patch/minitest/minitest/mock.rbs +0 -60
  52. data/examples/rails/patch/minitest/minitest/parallel/executor.rbs +0 -42
  53. data/examples/rails/patch/minitest/minitest/parallel/test/class_methods.rbs +0 -6
  54. data/examples/rails/patch/minitest/minitest/parallel/test.rbs +0 -3
  55. data/examples/rails/patch/minitest/minitest/parallel.rbs +0 -2
  56. data/examples/rails/patch/minitest/minitest/pride_io.rbs +0 -54
  57. data/examples/rails/patch/minitest/minitest/pride_lol.rbs +0 -17
  58. data/examples/rails/patch/minitest/minitest/progress_reporter.rbs +0 -11
  59. data/examples/rails/patch/minitest/minitest/reportable.rbs +0 -51
  60. data/examples/rails/patch/minitest/minitest/reporter.rbs +0 -5
  61. data/examples/rails/patch/minitest/minitest/result.rbs +0 -28
  62. data/examples/rails/patch/minitest/minitest/runnable.rbs +0 -131
  63. data/examples/rails/patch/minitest/minitest/skip.rbs +0 -6
  64. data/examples/rails/patch/minitest/minitest/spec/dsl/instance_methods.rbs +0 -48
  65. data/examples/rails/patch/minitest/minitest/spec/dsl.rbs +0 -125
  66. data/examples/rails/patch/minitest/minitest/spec.rbs +0 -10
  67. data/examples/rails/patch/minitest/minitest/statistics_reporter.rbs +0 -76
  68. data/examples/rails/patch/minitest/minitest/summary_reporter.rbs +0 -26
  69. data/examples/rails/patch/minitest/minitest/test/lifecycle_hooks.rbs +0 -92
  70. data/examples/rails/patch/minitest/minitest/test.rbs +0 -76
  71. data/examples/rails/patch/minitest/minitest/unexpected_error.rbs +0 -10
  72. data/examples/rails/patch/minitest/minitest/unit/test_case.rbs +0 -3
  73. data/examples/rails/patch/minitest/minitest/unit.rbs +0 -5
  74. data/examples/rails/patch/minitest/minitest.rbs +0 -966
  75. data/examples/rails/patch/pg/simple_decoder.rbs +0 -4
  76. data/examples/rails/patch/pg.rbs +0 -2
  77. data/examples/rails/patch/qc/queue.rbs +0 -2
  78. data/examples/rails/patch/qc.rbs +0 -2
  79. data/examples/rails/patch/que/job.rbs +0 -2
  80. data/examples/rails/patch/que.rbs +0 -2
  81. data/examples/rails/patch/rack/cache/entity_store.rbs +0 -2
  82. data/examples/rails/patch/rack/cache/meta_store.rbs +0 -2
  83. data/examples/rails/patch/rack/cache.rbs +0 -2
  84. data/examples/rails/patch/rack/session/dalli.rbs +0 -2
  85. data/examples/rails/patch/rack/session.rbs +0 -2
  86. data/examples/rails/patch/rboc.rbs +0 -2
  87. data/examples/rails/patch/rdoc/generator/sdoc.rbs +0 -3
  88. data/examples/rails/patch/rdoc/generator.rbs +0 -2
  89. data/examples/rails/patch/rdoc/task.rbs +0 -2
  90. data/examples/rails/patch/ripper.rbs +0 -2
  91. data/examples/rails/patch/sidekiq/worker.rbs +0 -2
  92. data/examples/rails/patch/sidekiq.rbs +0 -2
  93. data/examples/rails/patch/sneakers/worker.rbs +0 -2
  94. data/examples/rails/patch/sneakers.rbs +0 -2
  95. data/examples/rails/patch/sucker_punch/job.rbs +0 -2
  96. data/examples/rails/patch/sucker_punch.rbs +0 -2
  97. data/examples/rails/patch/thor/actions/create_file.rbs +0 -2
  98. data/examples/rails/patch/thor/actions.rbs +0 -2
  99. data/examples/rails/patch/thor/error.rbs +0 -2
  100. data/examples/rails/patch/thor/group.rbs +0 -2
  101. data/examples/rails/patch/thor.rbs +0 -2
  102. data/lib/orthoses/active_model/known_sig/7.0/serialization.rbs +0 -4
  103. data/lib/orthoses/active_model/known_sig/7.0/validations.rbs +0 -4
  104. data/lib/orthoses/active_model/known_sig.rb +0 -21
  105. data/lib/orthoses/active_record/known_sig/6.0/result.rbs +0 -5
  106. data/lib/orthoses/active_record/known_sig/6.1/result.rbs +0 -5
  107. data/lib/orthoses/active_record/known_sig/7.0/encryption/context.rbs +0 -9
  108. data/lib/orthoses/active_record/known_sig/7.0/result.rbs +0 -5
  109. data/lib/orthoses/active_record/known_sig.rb +0 -21
  110. data/lib/orthoses/active_support/concern.rb +0 -32
  111. data/lib/orthoses/active_support/known_sig/7.0/active_support/callbacks/callback_chain.rbs +0 -9
  112. data/lib/orthoses/active_support/known_sig/7.0/active_support/hash_with_indifferent_access.rbs +0 -6
  113. data/lib/orthoses/active_support/known_sig/7.0/hash_with_indifferent_access.rbs +0 -2
  114. data/lib/orthoses/active_support/known_sig/7.0/time.rbs +0 -68
  115. data/lib/orthoses/active_support/known_sig.rb +0 -21
  116. data/lib/orthoses/rails/known_sig_helper.rb +0 -22
@@ -0,0 +1,92 @@
1
+ stdlib_dependencies = %w[benchmark date digest json logger monitor mutex_m pathname singleton time minitest]
2
+ gem_dependencies = %w[nokogiri]
3
+ rails_dependencies = %w[]
4
+
5
+ VERSIONS.each do |version|
6
+ namespace version do
7
+ namespace :active_support do
8
+ export = "export/activesupport/#{version}"
9
+
10
+ desc "export to #{export}"
11
+ task :export do
12
+ sh "rm -fr #{export}"
13
+ sh "mkdir -p #{export}"
14
+
15
+ # minimum
16
+ sh "cp -a out/#{version}/active_support.rbs #{export}"
17
+ sh "cp -a out/#{version}/active_support #{export}"
18
+ sh "rm #{export}/active_support/railtie.rbs"
19
+
20
+ # core_ext
21
+ %w[
22
+ array benchmark big_decimal class date date_and_time date_time digest
23
+ enumerable file hash integer kernel load_error marshal module name_error numeric
24
+ object pathname range regexp securerandom string symbol time uri
25
+ ].each do |lib|
26
+ out = "out/#{version}/#{lib}"
27
+ sh "cp -a #{out} #{export}" if File.exist?(out)
28
+ sh "cp -a #{out}.rbs #{export}" if File.exist?("#{out}.rbs")
29
+ end
30
+
31
+ Pathname(export).join("EXTERNAL_TODO.rbs").write(<<~RBS)
32
+ # !!! GENERATED CODE !!!
33
+ # Please see generators/rails-generator
34
+
35
+ module DRb
36
+ module DRbUndumped
37
+ end
38
+ end
39
+ module Concurrent
40
+ class Map
41
+ end
42
+ end
43
+ RBS
44
+
45
+ case version
46
+ when "6.0", "6.1"
47
+ sh "rm -fr #{export}/uri"
48
+ when "7.0"
49
+ # deprecated
50
+ sh "rm -fr #{export}/uri{,.rbs}"
51
+ end
52
+
53
+ generate_test_script(
54
+ gem: :activesupport,
55
+ version: version,
56
+ export: export,
57
+ stdlib_dependencies: stdlib_dependencies,
58
+ gem_dependencies: gem_dependencies,
59
+ rails_dependencies: rails_dependencies,
60
+ )
61
+
62
+ Pathname(export).join('_test').join('test.rb').write(<<~'RUBY')
63
+ # !!! GENERATED CODE !!!
64
+ # Please see generators/rails-generator
65
+
66
+ require 'active_support/all'
67
+
68
+ # Test ActiveSupport::NumericWithFormat
69
+ 42.to_s
70
+ 42.to_s(:phone)
71
+
72
+ 3.days.ago + 1.minute
73
+ RUBY
74
+ end
75
+
76
+ desc "validate version=#{version} gem=active_support"
77
+ task :validate do
78
+ stdlib_opt = stdlib_dependencies.map{"-r #{_1}"}.join(" ")
79
+ gem_opt = gem_dependencies.map{"-I ../../.gem_rbs_collection/#{_1}"}.join(" ")
80
+ rails_opt = rails_dependencies.map{"-I export/#{_1}/#{version}"}.join(" ")
81
+ sh "rbs #{stdlib_opt} #{gem_opt} #{rails_opt} -I #{export} validate --silent"
82
+ end
83
+
84
+ desc "install to ../../../gems/activesupport/#{version}"
85
+ task :install do
86
+ install_to = File.expand_path("../../../gems/activesupport/#{version}", __dir__)
87
+ sh "rm -fr #{install_to}"
88
+ sh "cp -a #{export} #{install_to}"
89
+ end
90
+ end
91
+ end
92
+ end
@@ -27,12 +27,12 @@ module Orthoses
27
27
  @loader.call
28
28
  end
29
29
 
30
- call_tracer.result.each do |method, argument|
31
- next unless method.receiver.kind_of?(Class)
32
- base_name = Utils.module_name(method.receiver)
30
+ call_tracer.captures.each do |capture|
31
+ next unless capture.method.receiver.kind_of?(Class)
32
+ base_name = Utils.module_name(capture.method.receiver)
33
33
  next unless base_name
34
34
 
35
- attribute = argument[:attribute] || :password
35
+ attribute = capture.argument[:attribute] || :password
36
36
  full_name = if ::ActiveModel::VERSION::MAJOR < 6
37
37
  "ActiveModel::SecurePassword::InstanceMethodsOnActivation"
38
38
  else
@@ -1,4 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'active_model/has_secure_password'
4
- require_relative 'active_model/known_sig'
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveRecord
5
+ # <= 6.0
6
+ # not implemented
7
+ # >= 6.1
8
+ # def delegated_type(role, types:, **options)
9
+ class DelegatedType
10
+ def initialize(loader)
11
+ @loader = loader
12
+ end
13
+
14
+ def call
15
+ target = begin
16
+ ::ActiveRecord::DelegatedType.instance_method(:delegated_type)
17
+ rescue NameError
18
+ Orthoses.logger.warn("[ActiveRecord::DelegatedType] Skip since `delegated_type' is not implemented")
19
+ return @loader.call
20
+ end
21
+ delegated_type = CallTracer.new
22
+ store = delegated_type.trace(target) do
23
+ @loader.call
24
+ end
25
+
26
+ delegated_type.captures.each do |capture|
27
+ base_name = Utils.module_name(capture.method.receiver) or next
28
+ role = capture.argument[:role]
29
+ types = capture.argument[:types]
30
+ options = capture.argument[:options]
31
+ primary_key = options[:primary_key] || "id"
32
+
33
+ content = store[base_name]
34
+ content << "def #{role}_class: () -> (#{types.join(' | ')})"
35
+ content << "def #{role}_name: () -> String"
36
+ content << "def build_#{role}: () -> (#{types.join(' | ')})"
37
+ types.each do |type|
38
+ scope_name = type.tableize.gsub("/", "_")
39
+ singular = scope_name.singularize
40
+ content << "def #{singular}?: () -> bool"
41
+ content << "def #{singular}: () -> #{type}?"
42
+ content << "def #{singular}_#{primary_key}: () -> Integer?"
43
+ end
44
+ end
45
+
46
+ store
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveRecord
5
+ # <= 6.1
6
+ # def enum(definitions)
7
+ # >= 7.0
8
+ # def enum(name = nil, values = nil, **options)
9
+ class Enum
10
+ def initialize(loader)
11
+ @loader = loader
12
+ end
13
+
14
+ def call
15
+ enum = CallTracer.new
16
+ store = enum.trace(::ActiveRecord::Enum.instance_method(:enum)) do
17
+ @loader.call
18
+ end
19
+
20
+ enum.captures.each do |capture|
21
+ base_name = Utils.module_name(capture.method.receiver) or next
22
+
23
+ if capture.argument[:definitions]
24
+ # on rails 6
25
+ definitions = capture.argument[:definitions].slice!(:_prefix, :_suffix, :_scopes, :_default)
26
+ options = capture.argument[:definitions].transform_keys { |key| :"#{key[1..-1]}" }
27
+ definitions.each { |name, values| _enum(store, base_name, name, values, **options) }
28
+ else
29
+ # on rails 7
30
+ name = capture.argument[:name]
31
+ values = capture.argument[:values]
32
+ options = capture.argument[:options]
33
+ if name
34
+ # rails 7 style
35
+ values, options = options, {} unless values
36
+ _enum(store, base_name, name, values, **options)
37
+ else
38
+ # rails 6 style
39
+ definitions = options.slice!(:_prefix, :_suffix, :_scopes, :_default)
40
+ options.transform_keys! { |key| :"#{key[1..-1]}" }
41
+
42
+ definitions.each { |name, values| _enum(store, base_name, name, values, **options) }
43
+ end
44
+ end
45
+ end
46
+
47
+ store
48
+ end
49
+
50
+ private
51
+
52
+ def _enum(store, base_name, name, values, prefix: nil, suffix: nil, **_options)
53
+ name = name.to_s
54
+
55
+ prefix = if prefix
56
+ prefix == true ? "#{name}_" : "#{prefix}_"
57
+ end
58
+
59
+ suffix = if suffix
60
+ suffix == true ? "_#{name}" : "_#{suffix}"
61
+ end
62
+
63
+ return_type_param = Hash === values ? "[String, String]" : "[String, Integer]"
64
+ store[base_name] << "def self.#{name.pluralize}: () -> ActiveSupport::HashWithIndifferentAccess#{return_type_param}"
65
+
66
+ pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
67
+ pairs.each do |label, value|
68
+ value_method_name = "#{prefix}#{label}#{suffix}"
69
+ enum_methods_content = store["#{base_name}::ActiveRecord_Enum_EnumMethods"]
70
+ enum_methods_content.header = "module #{base_name}::ActiveRecord_Enum_EnumMethods"
71
+ enum_methods_content << "def #{value_method_name}?: () -> bool"
72
+ enum_methods_content << "def #{value_method_name}!: () -> bool"
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveRecord
5
+ # def scope(name, body, &block)
6
+ class Scope
7
+ def initialize(loader)
8
+ @loader = loader
9
+ end
10
+
11
+ def call
12
+ scope = CallTracer.new
13
+ store = scope.trace(::ActiveRecord::Scoping::Named::ClassMethods.instance_method(:scope)) do
14
+ @loader.call
15
+ end
16
+
17
+ scope.captures.each do |capture|
18
+ base_name = Utils.module_name(capture.method.receiver) or next
19
+
20
+ name = capture.argument[:name]
21
+ body = capture.argument[:body]
22
+
23
+ definition = "#{name}: #{parameters_to_type(body.parameters)} -> #{base_name}::ActiveRecord_Relation"
24
+ store[base_name] << "def self.#{definition}"
25
+ store["#{base_name}::GeneratedRelationMethods"].header = "module #{base_name}::GeneratedRelationMethods"
26
+ store["#{base_name}::GeneratedRelationMethods"] << "def #{definition}"
27
+ end
28
+
29
+ store
30
+ end
31
+
32
+ private
33
+
34
+ def parameters_to_type(parameters)
35
+ # @type var res: Array[String]
36
+ res = []
37
+ # @type var block: String?
38
+ block = nil
39
+ parameters.each do |(type, name)|
40
+ case type
41
+ when :req
42
+ res << "untyped #{name}"
43
+ when :opt
44
+ res << "?untyped #{name}"
45
+ when :keyreq
46
+ res << "#{name}: untyped"
47
+ when :key
48
+ res << "?#{name}: untyped"
49
+ when :rest
50
+ res << "*untyped #{name}"
51
+ when :keyrest
52
+ res << "**untyped #{name}"
53
+ when :block
54
+ block = " { (*untyped) -> untyped }"
55
+ else
56
+ raise "unexpected: #{type}"
57
+ end
58
+ end
59
+ "(#{res.join(", ")})#{block}"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'active_record/belongs_to'
4
+ require_relative 'active_record/delegated_type'
5
+ require_relative 'active_record/enum'
4
6
  require_relative 'active_record/generated_attribute_methods'
5
7
  require_relative 'active_record/has_many'
6
8
  require_relative 'active_record/has_one'
7
- require_relative 'active_record/known_sig'
8
9
  require_relative 'active_record/query_methods'
10
+ require_relative 'active_record/scope'
@@ -28,22 +28,22 @@ module Orthoses
28
28
  @loader.call
29
29
  end
30
30
 
31
- call_tracer.result.each do |method, argument|
32
- receiver_name = Orthoses::Utils.module_name(method.receiver)
31
+ call_tracer.captures.each do |capture|
32
+ receiver_name = Orthoses::Utils.module_name(capture.method.receiver)
33
33
  next unless receiver_name
34
34
 
35
35
  methods = []
36
36
  if ::ActiveSupport::VERSION::MAJOR < 6
37
- options = argument[:attrs].extract_options!
38
- argument[:instance_reader] = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
39
- argument[:instance_writer] = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
40
- argument[:instance_predicate] = options.fetch(:instance_predicate, true)
41
- argument[:default_value] = options.fetch(:default, nil)
37
+ options = capture.argument[:attrs].extract_options!
38
+ capture.argument[:instance_reader] = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
39
+ capture.argument[:instance_writer] = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
40
+ capture.argument[:instance_predicate] = options.fetch(:instance_predicate, true)
41
+ capture.argument[:default_value] = options.fetch(:default, nil)
42
42
  end
43
43
 
44
44
  content = store[receiver_name]
45
45
 
46
- argument[:attrs].each do |name|
46
+ capture.argument[:attrs].each do |name|
47
47
  next unless @if.nil? || @if.call(method, name)
48
48
 
49
49
  # skip internal attribute
@@ -52,11 +52,11 @@ module Orthoses
52
52
  next if name == :attributes_to_define_after_schema_loads
53
53
 
54
54
  methods << "def self.#{name}: () -> untyped"
55
- methods << "def self.#{name}?: () -> bool" if argument[:instance_predicate]
55
+ methods << "def self.#{name}?: () -> bool" if capture.argument[:instance_predicate]
56
56
  methods << "def self.#{name}=: (untyped value) -> untyped"
57
- methods << "def #{name}: () -> untyped" if argument[:instance_reader]
58
- methods << "def #{name}?: () -> bool" if argument[:instance_predicate] && argument[:instance_reader]
59
- methods << "def #{name}=: (untyped value) -> untyped" if argument[:instance_writer]
57
+ methods << "def #{name}: () -> untyped" if capture.argument[:instance_reader]
58
+ methods << "def #{name}?: () -> bool" if capture.argument[:instance_predicate] && capture.argument[:instance_reader]
59
+ methods << "def #{name}=: (untyped value) -> untyped" if capture.argument[:instance_writer]
60
60
  # In RBS, `foo=` and attr_writer :foo cannot live together.
61
61
  content.body.delete_if { |line| line.start_with?("attr_writer #{name}:") }
62
62
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveSupport
5
+ # <= 6.1
6
+ # def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true)
7
+ # >= 7
8
+ # def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil)
9
+ class Configurable
10
+ def initialize(loader)
11
+ @loader = loader
12
+ end
13
+
14
+ def call
15
+ config_accessor = CallTracer.new
16
+ store = config_accessor.trace(::ActiveSupport::Configurable::ClassMethods.instance_method(:config_accessor)) do
17
+ @loader.call
18
+ end
19
+ config_accessor.captures.each do |capture|
20
+ mod_name = Utils.module_name(capture.method.receiver) or next
21
+ content = store[mod_name]
22
+ capture.argument[:names].each do |name|
23
+ content << "def self.#{name}: () -> untyped"
24
+ content << "def self.#{name}=: (untyped value) -> untyped"
25
+ if capture.argument[:instance_accessor]
26
+ content << "def #{name}: () -> untyped" if capture.argument[:instance_reader]
27
+ content << "def #{name}=: (untyped value) -> untyped" if capture.argument[:instance_writer]
28
+ end
29
+ end
30
+ end
31
+
32
+ store
33
+ end
34
+ end
35
+ end
36
+ end
@@ -24,41 +24,41 @@ module Orthoses
24
24
 
25
25
  resource = Resource.new(store)
26
26
 
27
- delegate.result.each do |method, argument|
28
- receiver_name = Utils.module_name(method.receiver) or next
27
+ delegate.captures.each do |capture|
28
+ receiver_name = Utils.module_name(capture.method.receiver) or next
29
29
  receiver_content = store[receiver_name]
30
- case argument[:to]
30
+ case capture.argument[:to]
31
31
  when Module
32
- to_module_name = Utils.module_name(argument[:to]) or next
33
- argument[:methods].each do |arg|
32
+ to_module_name = Utils.module_name(capture.argument[:to]) or next
33
+ capture.argument[:methods].each do |arg|
34
34
  if sig = resource.build_signature(to_module_name, arg, :singleton, false)
35
35
  receiver_content << "# defined by `delegate` to: #{to_module_name}"
36
36
  receiver_content << sig
37
37
  else
38
- Orthoses.logger.warn("[ActiveSupport::Delegation] Ignore #{arg.inspect}")
38
+ Orthoses.logger.warn("[ActiveSupport::Delegation] Ignore since missing type for #{to_module_name}.#{arg.inspect} in #{capture.argument.inspect}")
39
39
  end
40
40
  end
41
41
  else
42
- to_name = argument[:to].to_s.to_sym
42
+ to_name = capture.argument[:to].to_s.to_sym
43
43
  tag, to_return_type = resource.find(receiver_name, to_name, :instance, false)
44
44
  raise "bug" if tag == :multi
45
45
  if to_return_type.nil?
46
- Orthoses.logger.warn("[ActiveSupport::Delegation] Ignore #{argument.inspect}")
46
+ Orthoses.logger.warn("[ActiveSupport::Delegation] Ignore since missing type for #{receiver_name}##{to_name.inspect} in #{capture.argument.inspect}")
47
47
  next
48
48
  end
49
49
  if to_return_type.instance_of?(RBS::Types::Bases::Any)
50
- argument[:methods].each do |method|
51
- receiver_content << "# defined by `delegate` to: :#{to_name}(#{to_return_type})"
50
+ capture.argument[:methods].each do |method|
51
+ receiver_content << "# defined by `delegate` to: #{to_return_type}##{to_name}"
52
52
  receiver_content << "def #{method}: (*untyped, **untyped) -> untyped"
53
53
  end
54
54
  else
55
55
  to_typename = to_return_type.name.relative!.to_s
56
- argument[:methods].each do |method|
56
+ capture.argument[:methods].each do |method|
57
57
  if sig = resource.build_signature(to_typename, method, :instance, true)
58
- receiver_content << "# defined by `delegate` to: :#{to_name}(#{to_return_type})"
58
+ receiver_content << "# defined by `delegate` to #{to_return_type}##{to_name}"
59
59
  receiver_content << sig
60
60
  else
61
- Orthoses.logger.warn("[ActiveSupport::Delegation] Ignore #{method.inspect}")
61
+ Orthoses.logger.warn("[ActiveSupport::Delegation] Ignore since missing type for #{to_typename}##{method.inspect} in #{capture.argument.inspect}")
62
62
  end
63
63
  end
64
64
  end
@@ -146,7 +146,7 @@ module Orthoses
146
146
  when RBS::AST::Members::Mixin, RBS::AST::Members::LocationOnly
147
147
  next
148
148
  else
149
- binding.irb
149
+ raise "bug: #{member.class} is not supported yet"
150
150
  end
151
151
  end
152
152
 
@@ -22,14 +22,14 @@ module Orthoses
22
22
  end
23
23
  end
24
24
 
25
- mattr_reader.result.each do |method, argument|
26
- base = Orthoses::Utils.module_name(method.receiver) || next
25
+ mattr_reader.captures.each do |capture|
26
+ base = Orthoses::Utils.module_name(capture.method.receiver) || next
27
27
  methods = []
28
- argument[:syms].each do |sym|
28
+ capture.argument[:syms].each do |sym|
29
29
  next unless @if.nil? || @if.call(method, sym)
30
30
 
31
31
  methods << "def self.#{sym}: () -> untyped"
32
- if argument[:instance_reader] && argument[:instance_accessor]
32
+ if capture.argument[:instance_reader] && capture.argument[:instance_accessor]
33
33
  methods << "def #{sym}: () -> untyped"
34
34
  end
35
35
  end
@@ -38,14 +38,14 @@ module Orthoses
38
38
  store[base].concat(methods)
39
39
  end
40
40
 
41
- mattr_writer.result.each do |method, argument|
42
- base = Orthoses::Utils.module_name(method.receiver) || next
41
+ mattr_writer.captures.each do |capture|
42
+ base = Orthoses::Utils.module_name(capture.method.receiver) || next
43
43
  methods = []
44
- argument[:syms].each do |sym|
44
+ capture.argument[:syms].each do |sym|
45
45
  next unless @if.nil? || @if.call(method, sym)
46
46
 
47
47
  methods << "def self.#{sym}=: (untyped val) -> untyped"
48
- if argument[:instance_writer] && argument[:instance_accessor]
48
+ if capture.argument[:instance_writer] && capture.argument[:instance_accessor]
49
49
  methods << "def #{sym}=: (untyped val) -> untyped"
50
50
  end
51
51
  end
@@ -7,11 +7,6 @@ module Orthoses
7
7
  @loader = loader
8
8
  end
9
9
 
10
- LOAD_PATHS = [
11
- File.expand_path("known_sig/time.rbs", __dir__),
12
- File.expand_path("known_sig/active_support/time_with_zone.rbs", __dir__),
13
- ]
14
-
15
10
  # Time <= (known Time)
16
11
  # TimeWithZone <= (known TimeWithZone, known Time, core Time)
17
12
  def call
@@ -27,17 +22,23 @@ module Orthoses
27
22
 
28
23
  private
29
24
 
30
- NOT_DELEGATE_METHODS = %i[
25
+ NOT_DELEGATE_METHODS = Set.new(%i[
31
26
  utc
32
27
  getgm
33
28
  getutc
34
29
  gmtime
35
30
  localtime
36
- ]
31
+ ])
32
+
33
+ TYPE_MERGE_METHODS = Set.new(%i[
34
+ +
35
+ -
36
+ ])
37
37
 
38
38
  def each_line_from_core_time_definition(store)
39
39
  type_name_time = TypeName("::Time")
40
- env = Utils.rbs_environment(collection: true).dup
40
+ type_name_time_with_zone = TypeName("::ActiveSupport::TimeWithZone")
41
+ env = Utils.rbs_environment(collection: true, cache: false)
41
42
  env << store["Time"].to_decl
42
43
  env << store["DateAndTime"].to_decl
43
44
  env << store["DateAndTime::Zones"].to_decl
@@ -53,6 +54,7 @@ module Orthoses
53
54
  one_ancestors.included_modules.each do |included_module|
54
55
  yield "include #{included_module.source.name}"
55
56
  end
57
+ twz_methods = builder.build_instance(type_name_time_with_zone).methods
56
58
  builder.build_instance(type_name_time).methods.each do |sym, definition_method|
57
59
  next if !definition_method.public?
58
60
  definition_method.defs.reject! do |type_def|
@@ -70,7 +72,18 @@ module Orthoses
70
72
  end
71
73
 
72
74
  if definition_method.alias_of.nil?
73
- yield "def #{sym}: #{definition_method.method_types.join(" | ")}"
75
+ method_types = definition_method.method_types
76
+
77
+ if TYPE_MERGE_METHODS.include?(sym)
78
+ if twz_definition_method = twz_methods[sym]
79
+ twz_definition_method.defs.each do |type_def|
80
+ if type_def.implemented_in == type_name_time_with_zone
81
+ method_types << type_def.type
82
+ end
83
+ end
84
+ end
85
+ end
86
+ yield "def #{sym}: #{method_types.join(" | ")}"
74
87
  else
75
88
  yield "alias #{sym} #{definition_method.alias_of.defs.first.member.name}"
76
89
  end
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'active_support/class_attribute'
4
- require_relative 'active_support/concern'
4
+ require_relative 'active_support/configurable'
5
5
  require_relative 'active_support/delegation'
6
6
  require_relative 'active_support/mattr_accessor'
7
7
  require_relative 'active_support/time_with_zone'
8
- require_relative 'active_support/known_sig'
9
8
 
10
9
  module Orthoses
11
10
  module ActiveSupport
@@ -15,11 +14,9 @@ module Orthoses
15
14
  # end
16
15
  def self.each
17
16
  yield ClassAttribute
18
- yield Concern
19
17
  yield Delegation
20
18
  yield MattrAccessor
21
19
  yield TimeWithZone
22
- yield KnownSig
23
20
  end
24
21
  end
25
22
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Orthoses
4
4
  module Rails
5
- VERSION = "0.3.0"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
@@ -3,7 +3,6 @@
3
3
  require 'orthoses'
4
4
 
5
5
  require_relative "rails/version"
6
- require_relative "rails/known_sig_helper"
7
6
 
8
7
  require_relative 'active_model'
9
8
  require_relative 'active_record'
@@ -32,5 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
33
33
  spec.require_paths = ["lib"]
34
34
 
35
- spec.add_dependency "orthoses"
35
+ spec.add_dependency "orthoses", ">= 0.10"
36
36
  end