orthoses-rails 0.1.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +39 -0
  3. data/examples/rails/Rakefile +373 -0
  4. data/examples/rails/known_sig/action_cable/connection/test_cookie_jar.rbs +2 -0
  5. data/examples/rails/known_sig/action_controller/metal.rbs +4 -0
  6. data/examples/rails/known_sig/action_dispatch/cookies/cookie_jar.rbs +3 -0
  7. data/examples/rails/known_sig/action_dispatch/response.rbs +4 -0
  8. data/examples/rails/patch/drb/drb_undumped.rbs +2 -0
  9. data/examples/rails/patch/drb.rbs +2 -0
  10. data/examples/rails/patch/erubi/engine.rbs +4 -0
  11. data/examples/rails/patch/erubi.rbs +2 -0
  12. data/examples/rails/patch/minitest/kernel.rbs +44 -0
  13. data/examples/rails/patch/minitest/minitest/abstract_reporter.rbs +49 -0
  14. data/examples/rails/patch/minitest/minitest/assertion.rbs +16 -0
  15. data/examples/rails/patch/minitest/minitest/assertions.rbs +545 -0
  16. data/examples/rails/patch/minitest/minitest/backtrace_filter.rbs +16 -0
  17. data/examples/rails/patch/minitest/minitest/bench_spec.rbs +101 -0
  18. data/examples/rails/patch/minitest/minitest/benchmark.rbs +258 -0
  19. data/examples/rails/patch/minitest/minitest/composite_reporter.rbs +25 -0
  20. data/examples/rails/patch/minitest/minitest/expectations.rbs +21 -0
  21. data/examples/rails/patch/minitest/minitest/guard.rbs +64 -0
  22. data/examples/rails/patch/minitest/minitest/mock.rbs +60 -0
  23. data/examples/rails/patch/minitest/minitest/parallel/executor.rbs +42 -0
  24. data/examples/rails/patch/minitest/minitest/parallel/test/class_methods.rbs +6 -0
  25. data/examples/rails/patch/minitest/minitest/parallel/test.rbs +3 -0
  26. data/examples/rails/patch/minitest/minitest/parallel.rbs +2 -0
  27. data/examples/rails/patch/minitest/minitest/pride_io.rbs +54 -0
  28. data/examples/rails/patch/minitest/minitest/pride_lol.rbs +17 -0
  29. data/examples/rails/patch/minitest/minitest/progress_reporter.rbs +11 -0
  30. data/examples/rails/patch/minitest/minitest/reportable.rbs +51 -0
  31. data/examples/rails/patch/minitest/minitest/reporter.rbs +5 -0
  32. data/examples/rails/patch/minitest/minitest/result.rbs +28 -0
  33. data/examples/rails/patch/minitest/minitest/runnable.rbs +131 -0
  34. data/examples/rails/patch/minitest/minitest/skip.rbs +6 -0
  35. data/examples/rails/patch/minitest/minitest/spec/dsl/instance_methods.rbs +48 -0
  36. data/examples/rails/patch/minitest/minitest/spec/dsl.rbs +125 -0
  37. data/examples/rails/patch/minitest/minitest/spec.rbs +10 -0
  38. data/examples/rails/patch/minitest/minitest/statistics_reporter.rbs +76 -0
  39. data/examples/rails/patch/minitest/minitest/summary_reporter.rbs +26 -0
  40. data/examples/rails/patch/minitest/minitest/test/lifecycle_hooks.rbs +92 -0
  41. data/examples/rails/patch/minitest/minitest/test.rbs +76 -0
  42. data/examples/rails/patch/minitest/minitest/unexpected_error.rbs +10 -0
  43. data/examples/rails/patch/minitest/minitest/unit/test_case.rbs +3 -0
  44. data/examples/rails/patch/minitest/minitest/unit.rbs +5 -0
  45. data/examples/rails/patch/minitest/minitest.rbs +966 -0
  46. data/examples/rails/patch/pg/simple_decoder.rbs +4 -0
  47. data/examples/rails/patch/pg.rbs +2 -0
  48. data/examples/rails/patch/qc/queue.rbs +2 -0
  49. data/examples/rails/patch/qc.rbs +2 -0
  50. data/examples/rails/patch/que/job.rbs +2 -0
  51. data/examples/rails/patch/que.rbs +2 -0
  52. data/examples/rails/patch/rack/cache/entity_store.rbs +2 -0
  53. data/examples/rails/patch/rack/cache/meta_store.rbs +2 -0
  54. data/examples/rails/patch/rack/cache.rbs +2 -0
  55. data/examples/rails/patch/rack/session/dalli.rbs +2 -0
  56. data/examples/rails/patch/rack/session.rbs +2 -0
  57. data/examples/rails/patch/rboc.rbs +2 -0
  58. data/examples/rails/patch/rdoc/generator/sdoc.rbs +3 -0
  59. data/examples/rails/patch/rdoc/generator.rbs +2 -0
  60. data/examples/rails/patch/rdoc/task.rbs +2 -0
  61. data/examples/rails/patch/ripper.rbs +2 -0
  62. data/examples/rails/patch/sidekiq/worker.rbs +2 -0
  63. data/examples/rails/patch/sidekiq.rbs +2 -0
  64. data/examples/rails/patch/sneakers/worker.rbs +2 -0
  65. data/examples/rails/patch/sneakers.rbs +2 -0
  66. data/examples/rails/patch/sucker_punch/job.rbs +2 -0
  67. data/examples/rails/patch/sucker_punch.rbs +2 -0
  68. data/examples/rails/patch/thor/actions/create_file.rbs +2 -0
  69. data/examples/rails/patch/thor/actions.rbs +2 -0
  70. data/examples/rails/patch/thor/error.rbs +2 -0
  71. data/examples/rails/patch/thor/group.rbs +2 -0
  72. data/examples/rails/patch/thor.rbs +2 -0
  73. data/lib/orthoses/active_model/has_secure_password.rb +24 -13
  74. data/lib/orthoses/active_model/known_sig/7.0/serialization.rbs +4 -0
  75. data/lib/orthoses/active_model/known_sig/7.0/validations.rbs +4 -0
  76. data/lib/orthoses/active_model/known_sig.rb +21 -0
  77. data/lib/orthoses/active_model.rb +4 -0
  78. data/lib/orthoses/active_record/belongs_to.rb +10 -4
  79. data/lib/orthoses/active_record/generated_attribute_methods.rb +6 -4
  80. data/lib/orthoses/active_record/has_many.rb +6 -6
  81. data/lib/orthoses/active_record/has_one.rb +5 -4
  82. data/lib/orthoses/active_record/known_sig/6.0/result.rbs +5 -0
  83. data/lib/orthoses/active_record/known_sig/6.1/result.rbs +5 -0
  84. data/lib/orthoses/active_record/known_sig/7.0/encryption/context.rbs +9 -0
  85. data/lib/orthoses/active_record/known_sig/7.0/result.rbs +5 -0
  86. data/lib/orthoses/active_record/known_sig.rb +21 -0
  87. data/lib/orthoses/active_record/query_methods.rb +32 -0
  88. data/lib/orthoses/active_record.rb +8 -0
  89. data/lib/orthoses/active_support/class_attribute.rb +30 -17
  90. data/lib/orthoses/active_support/configurable.rb +36 -0
  91. data/lib/orthoses/active_support/delegation.rb +158 -0
  92. data/lib/orthoses/active_support/known_sig/7.0/active_support/callbacks/callback_chain.rbs +9 -0
  93. data/lib/orthoses/active_support/known_sig/7.0/active_support/hash_with_indifferent_access.rbs +6 -0
  94. data/lib/orthoses/active_support/known_sig/7.0/active_support/multibyte/chars.rbs +7 -0
  95. data/lib/orthoses/active_support/known_sig/7.0/hash_with_indifferent_access.rbs +2 -0
  96. data/lib/orthoses/active_support/known_sig/{time.rbs → 7.0/time.rbs} +4 -0
  97. data/lib/orthoses/active_support/known_sig.rb +21 -0
  98. data/lib/orthoses/active_support/mattr_accessor.rb +21 -14
  99. data/lib/orthoses/active_support/time_with_zone.rb +13 -15
  100. data/lib/orthoses/active_support.rb +24 -0
  101. data/lib/orthoses/rails/known_sig_helper.rb +22 -0
  102. data/lib/orthoses/rails/version.rb +1 -1
  103. data/lib/orthoses/rails.rb +4 -11
  104. data/orthoses-rails.gemspec +2 -2
  105. metadata +97 -9
  106. data/lib/orthoses/active_support/concern.rb +0 -22
  107. data/lib/orthoses/active_support/known_sig/active_support/time_with_zone.rbs +0 -4
@@ -0,0 +1,4 @@
1
+ module PG
2
+ class SimpleDecoder
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ module PG
2
+ end
@@ -0,0 +1,2 @@
1
+ class QC::Queue
2
+ end
@@ -0,0 +1,2 @@
1
+ class QC
2
+ end
@@ -0,0 +1,2 @@
1
+ class Que::Job
2
+ end
@@ -0,0 +1,2 @@
1
+ module Que
2
+ end
@@ -0,0 +1,2 @@
1
+ class Rack::Cache::EntityStore
2
+ end
@@ -0,0 +1,2 @@
1
+ class Rack::Cache::MetaStore
2
+ end
@@ -0,0 +1,2 @@
1
+ module Rack::Cache
2
+ end
@@ -0,0 +1,2 @@
1
+ class Rack::Session::Dalli
2
+ end
@@ -0,0 +1,2 @@
1
+ module Rack::Session
2
+ end
@@ -0,0 +1,2 @@
1
+ module RDoc
2
+ end
@@ -0,0 +1,3 @@
1
+ # defined in sdoc gem
2
+ class RDoc::Generator::SDoc
3
+ end
@@ -0,0 +1,2 @@
1
+ module RDoc::Generator
2
+ end
@@ -0,0 +1,2 @@
1
+ class RDoc::Task
2
+ end
@@ -0,0 +1,2 @@
1
+ class Ripper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Sidekiq::Worker
2
+ end
@@ -0,0 +1,2 @@
1
+ module Sidekiq
2
+ end
@@ -0,0 +1,2 @@
1
+ module Sneakers::Worker
2
+ end
@@ -0,0 +1,2 @@
1
+ module Sneakers
2
+ end
@@ -0,0 +1,2 @@
1
+ module SuckerPunch::Job
2
+ end
@@ -0,0 +1,2 @@
1
+ module SuckerPunch
2
+ end
@@ -0,0 +1,2 @@
1
+ class Thor::Actions::CreateFile
2
+ end
@@ -0,0 +1,2 @@
1
+ module Thor::Actions
2
+ end
@@ -0,0 +1,2 @@
1
+ class Thor::Error < ::StandardError
2
+ end
@@ -0,0 +1,2 @@
1
+ class Thor::Group
2
+ end
@@ -0,0 +1,2 @@
1
+ class Thor
2
+ end
@@ -13,35 +13,46 @@ module Orthoses
13
13
  end
14
14
 
15
15
  def call
16
- target_method = ::ActiveRecord::Base.method(:has_secure_password)
16
+ target_method = begin
17
+ ::ActiveModel::SecurePassword::ClassMethods.instance_method(:has_secure_password)
18
+ rescue NameError => err
19
+ Orthoses.logger.warn("Run `require 'active_support/concern'; require 'active_model/secure_password'` and retry because #{err}")
20
+ require 'active_support/concern'
21
+ require 'active_model/secure_password'
22
+ retry
23
+ end
17
24
  call_tracer = Orthoses::CallTracer.new
18
25
 
19
- result = call_tracer.trace(target_method) do
26
+ store = call_tracer.trace(target_method) do
20
27
  @loader.call
21
28
  end
22
29
 
23
- call_tracer.result.each do |method, argument|
24
- base = method.receiver.to_s
25
- if argument[:attribute].nil? # < 6.0
26
- result[base].delete_if { |line| line == "include ActiveModel::SecurePassword::InstanceMethodsOnActivation" }
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
+ next unless base_name
34
+
35
+ attribute = capture.argument[:attribute] || :password
36
+ full_name = if ::ActiveModel::VERSION::MAJOR < 6
37
+ "ActiveModel::SecurePassword::InstanceMethodsOnActivation"
27
38
  else
28
- result[base].delete_if { |line| line.start_with?("include #<InstanceMethodsOnActivation:") }
39
+ "#{base_name}::ActiveModel_SecurePassword_InstanceMethodsOnActivation_#{attribute}"
29
40
  end
30
- attribute = argument[:attribute] || :password
31
- mod_name = "ActiveModel_SecurePassword_InstanceMethodsOnActivation_#{attribute}"
41
+
32
42
  lines = []
33
43
  lines << "attr_reader #{attribute}: String?"
34
44
  lines << "def #{attribute}=: (String) -> String"
35
45
  lines << "def #{attribute}_confirmation=: (String) -> String"
36
- lines << "def authenticate_#{attribute}: (String) -> (#{base} | false)"
46
+ lines << "def authenticate_#{attribute}: (String) -> (#{base_name} | false)"
37
47
  if attribute == :password
38
48
  lines << "alias authenticate authenticate_password"
39
49
  end
40
- result["module #{base}::#{mod_name}"].concat(lines)
41
- result[base] << "include #{mod_name}"
50
+ store[full_name].header = "module #{full_name}"
51
+ store[full_name].concat(lines)
52
+ store[base_name] << "include #{full_name}"
42
53
  end
43
54
 
44
- result
55
+ store
45
56
  end
46
57
  end
47
58
  end
@@ -0,0 +1,4 @@
1
+ module ActiveModel::Serialization
2
+ # https://github.com/ruby/rbs/issues/1008
3
+ def send: (Object::name name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
4
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveModel::Validations
2
+ # https://github.com/ruby/rbs/issues/1008
3
+ def send: (Object::name name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
4
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveModel
5
+ class KnownSig
6
+ include Orthoses::Rails::KnownSigHelper
7
+
8
+ def initialize(loader)
9
+ @loader = loader
10
+ end
11
+
12
+ def call
13
+ @loader.call.tap do |store|
14
+ paths = best_version_paths(::ActiveModel::VERSION::STRING, __dir__)
15
+ env = Content::Environment.load_from_paths(paths)
16
+ env.write_to(store: store)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'active_model/has_secure_password'
4
+ require_relative 'active_model/known_sig'
@@ -11,6 +11,7 @@ module Orthoses
11
11
  @loader.call.tap do |store|
12
12
  ::ActiveRecord::Base.descendants.each do |base|
13
13
  next if base.abstract_class?
14
+ base_name = Orthoses::Utils.module_name(base) || next
14
15
 
15
16
  lines = base.reflect_on_all_associations(:belongs_to).flat_map do |ref|
16
17
  # FIXME: Can I get list of class for polymorphic?
@@ -30,11 +31,16 @@ module Orthoses
30
31
  end
31
32
  end
32
33
 
33
- generated_association_methods = "#{base}::GeneratedAssociationMethods"
34
- store["module #{generated_association_methods}"].concat(lines)
34
+ generated_association_methods = "#{base_name}::GeneratedAssociationMethods"
35
35
 
36
- code = "include #{generated_association_methods}"
37
- store[base.to_s] << code
36
+ store[generated_association_methods].tap do |content|
37
+ content.header = "module #{generated_association_methods}"
38
+ content.concat(lines)
39
+ end
40
+
41
+ store[base_name].tap do |content|
42
+ store[base_name] << "include #{generated_association_methods}"
43
+ end
38
44
  end
39
45
  end
40
46
  end
@@ -12,9 +12,7 @@ module Orthoses
12
12
  ::ActiveRecord::Base.descendants.each do |klass|
13
13
  next if klass.abstract_class?
14
14
 
15
- name = klass.to_s
16
- generated_attribute_methods = "#{name}::AttributeMethods::GeneratedAttributeMethods"
17
- store[name] << "include #{generated_attribute_methods}"
15
+ name = Utils.module_name(klass) || next
18
16
  lines = klass.columns.flat_map do |col|
19
17
  req = sql_type_to_rbs(col.type)
20
18
  opt = "#{req}?"
@@ -41,7 +39,11 @@ module Orthoses
41
39
  "def clear_#{col.name}_change: () -> void",
42
40
  ]
43
41
  end
44
- store["module #{generated_attribute_methods}"].concat(lines)
42
+ generated_attribute_methods = "#{name}::AttributeMethods::GeneratedAttributeMethods"
43
+ store[name] << "include #{generated_attribute_methods}"
44
+
45
+ store[generated_attribute_methods].header = "module #{generated_attribute_methods}"
46
+ store[generated_attribute_methods].concat(lines)
45
47
  end
46
48
  end
47
49
  end
@@ -11,9 +11,9 @@ module Orthoses
11
11
  @loader.call.tap do |store|
12
12
  ::ActiveRecord::Base.descendants.each do |base|
13
13
  next if base.abstract_class?
14
+ base_name = Utils.module_name(base) || next
14
15
 
15
- generated_association_methods = "#{base}::GeneratedAssociationMethods"
16
- collection_proxy = "#{base}::ActiveRecord_Associations_CollectionProxy"
16
+ collection_proxy = "#{base_name}::ActiveRecord_Associations_CollectionProxy"
17
17
 
18
18
  lines = base.reflect_on_all_associations(:has_many).flat_map do |ref|
19
19
  singular_name = ref.name.to_s.singularize
@@ -26,10 +26,10 @@ module Orthoses
26
26
  ]
27
27
  end
28
28
 
29
- store["module #{generated_association_methods}"].concat(lines)
30
-
31
- code = "include #{generated_association_methods}"
32
- store[base.to_s] << code
29
+ generated_association_methods = "#{base_name}::GeneratedAssociationMethods"
30
+ store[generated_association_methods].header = "module #{generated_association_methods}"
31
+ store[generated_association_methods].concat(lines)
32
+ store[base_name] << "include #{generated_association_methods}"
33
33
  end
34
34
  end
35
35
  end
@@ -11,6 +11,7 @@ module Orthoses
11
11
  @loader.call.tap do |store|
12
12
  ::ActiveRecord::Base.descendants.each do |base|
13
13
  next if base.abstract_class?
14
+ base_name = Utils.module_name(base) || next
14
15
 
15
16
  lines = base.reflect_on_all_associations(:has_one).flat_map do |ref|
16
17
  type = ref.klass.to_s
@@ -26,11 +27,11 @@ module Orthoses
26
27
  ]
27
28
  end
28
29
 
29
- generated_association_methods = "#{base}::GeneratedAssociationMethods"
30
- store["module #{generated_association_methods}"].concat(lines)
30
+ generated_association_methods = "#{base_name}::GeneratedAssociationMethods"
31
+ store[generated_association_methods].header = "module #{generated_association_methods}"
32
+ store[generated_association_methods].concat(lines)
31
33
 
32
- code = "include #{generated_association_methods}"
33
- store[base.to_s] << code
34
+ store[base_name] << "include #{generated_association_methods}"
34
35
  end
35
36
  end
36
37
  end
@@ -0,0 +1,5 @@
1
+ class ActiveRecord::Result
2
+ include Enumerable[Hash[String, untyped]]
3
+ def each: () -> Enumerator[Hash[String, untyped], Array[Hash[String, untyped]]]
4
+ | () { (Hash[String, untyped]) -> void } -> Array[Hash[String, untyped]]
5
+ end
@@ -0,0 +1,5 @@
1
+ class ActiveRecord::Result
2
+ include Enumerable[Hash[String, untyped]]
3
+ def each: () -> Enumerator[Hash[String, untyped], Array[Hash[String, untyped]]]
4
+ | () { (Hash[String, untyped]) -> void } -> Array[Hash[String, untyped]]
5
+ end
@@ -0,0 +1,9 @@
1
+ # attr_accessor in #each
2
+ class ActiveRecord::Encryption::Context
3
+ attr_accessor key_provider: untyped
4
+ attr_accessor key_generator: untyped
5
+ attr_accessor cipher: untyped
6
+ attr_accessor message_serializer: untyped
7
+ attr_accessor encryptor: untyped
8
+ attr_accessor frozen_encryption: untyped
9
+ end
@@ -0,0 +1,5 @@
1
+ class ActiveRecord::Result
2
+ include Enumerable[Hash[String, untyped]]
3
+ def each: () -> Enumerator[Hash[String, untyped], Array[Hash[String, untyped]]]
4
+ | () { (Hash[String, untyped]) -> void } -> Array[Hash[String, untyped]]
5
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveRecord
5
+ class KnownSig
6
+ include Orthoses::Rails::KnownSigHelper
7
+
8
+ def initialize(loader)
9
+ @loader = loader
10
+ end
11
+
12
+ def call
13
+ @loader.call.tap do |store|
14
+ paths = best_version_paths(::ActiveRecord::VERSION::STRING, __dir__)
15
+ env = Content::Environment.load_from_paths(paths)
16
+ env.write_to(store: store)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveRecord
5
+ class QueryMethods
6
+ def initialize(loader)
7
+ @loader = loader
8
+ end
9
+
10
+ def call
11
+ @loader.call.tap do |store|
12
+ content = store["ActiveRecord::QueryMethods"]
13
+
14
+ ::ActiveRecord::Relation::VALUE_METHODS.each do |name|
15
+ method_name, type =
16
+ case name
17
+ when *::ActiveRecord::Relation::MULTI_VALUE_METHODS
18
+ ["#{name}_values", "::Array[untyped]"]
19
+ when *::ActiveRecord::Relation::SINGLE_VALUE_METHODS
20
+ ["#{name}_value", name == :create_with ? "::Hash[untyped, untyped]?" : "untyped"]
21
+ when *::ActiveRecord::Relation::CLAUSE_METHODS
22
+ ["#{name}_clause", name == :from ? "::ActiveRecord::Relation::FromClause" : "::ActiveRecord::Relation::WhereClause"]
23
+ end
24
+
25
+ content << "def #{method_name}: () -> #{type}"
26
+ content << "def #{method_name}=: (#{type} value) -> #{type}"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'active_record/belongs_to'
4
+ require_relative 'active_record/generated_attribute_methods'
5
+ require_relative 'active_record/has_many'
6
+ require_relative 'active_record/has_one'
7
+ require_relative 'active_record/known_sig'
8
+ require_relative 'active_record/query_methods'
@@ -15,24 +15,35 @@ module Orthoses
15
15
  end
16
16
 
17
17
  def call
18
- require 'active_support/core_ext/class/attribute'
19
- target_method = ::Class.instance_method(:class_attribute)
18
+ target_method = begin
19
+ ::Class.instance_method(:class_attribute)
20
+ rescue NameError => err
21
+ Orthoses.logger.warn("Run `require 'active_support/core_ext/class/attribute'` and retry because #{err}")
22
+ require 'active_support/core_ext/class/attribute'
23
+ retry
24
+ end
20
25
  call_tracer = Orthoses::CallTracer.new
21
26
 
22
- result = call_tracer.trace(target_method) do
27
+ store = call_tracer.trace(target_method) do
23
28
  @loader.call
24
29
  end
25
30
 
26
- call_tracer.result.each do |method, argument|
31
+ call_tracer.captures.each do |capture|
32
+ receiver_name = Orthoses::Utils.module_name(capture.method.receiver)
33
+ next unless receiver_name
34
+
27
35
  methods = []
28
- if ::ActiveSupport.version < Gem::Version.new("6.0")
29
- options = argument[:attrs].extract_options!
30
- argument[:instance_reader] = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
31
- argument[:instance_writer] = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
32
- argument[:instance_predicate] = options.fetch(:instance_predicate, true)
33
- argument[:default_value] = options.fetch(:default, nil)
36
+ if ::ActiveSupport::VERSION::MAJOR < 6
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)
34
42
  end
35
- argument[:attrs].each do |name|
43
+
44
+ content = store[receiver_name]
45
+
46
+ capture.argument[:attrs].each do |name|
36
47
  next unless @if.nil? || @if.call(method, name)
37
48
 
38
49
  # skip internal attribute
@@ -41,18 +52,20 @@ module Orthoses
41
52
  next if name == :attributes_to_define_after_schema_loads
42
53
 
43
54
  methods << "def self.#{name}: () -> untyped"
44
- methods << "def self.#{name}?: () -> bool" if argument[:instance_predicate]
55
+ methods << "def self.#{name}?: () -> bool" if capture.argument[:instance_predicate]
45
56
  methods << "def self.#{name}=: (untyped value) -> untyped"
46
- methods << "def #{name}: () -> untyped" if argument[:instance_reader]
47
- methods << "def #{name}?: () -> bool" if argument[:instance_predicate] && argument[:instance_reader]
48
- methods << "attr_writer #{name}: 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
+ # In RBS, `foo=` and attr_writer :foo cannot live together.
61
+ content.body.delete_if { |line| line.start_with?("attr_writer #{name}:") }
49
62
  end
50
63
  next if methods.empty?
51
64
 
52
- result[method.receiver.to_s].concat(methods)
65
+ content.concat(methods)
53
66
  end
54
67
 
55
- result
68
+ store
56
69
  end
57
70
  end
58
71
  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