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.
- checksums.yaml +4 -4
- data/README.md +31 -39
- data/examples/rails/Rakefile +139 -68
- data/examples/rails/config/database.yml +8 -0
- data/examples/rails/config/storage.yml +3 -0
- data/examples/rails/gemfiles/Gemfile_6_0 +16 -0
- data/examples/rails/gemfiles/Gemfile_6_0.lock +172 -0
- data/examples/rails/gemfiles/Gemfile_6_1 +15 -0
- data/examples/rails/gemfiles/Gemfile_6_1.lock +173 -0
- data/examples/rails/gemfiles/Gemfile_7_0 +15 -0
- data/examples/rails/gemfiles/Gemfile_7_0.lock +172 -0
- data/examples/rails/tasks/active_job.rake +95 -0
- data/examples/rails/tasks/active_model.rake +46 -0
- data/examples/rails/tasks/active_record.rake +83 -0
- data/examples/rails/tasks/active_storage.rake +94 -0
- data/examples/rails/tasks/active_support.rake +92 -0
- data/lib/orthoses/active_model/has_secure_password.rb +4 -4
- data/lib/orthoses/active_model.rb +0 -1
- data/lib/orthoses/active_record/delegated_type.rb +50 -0
- data/lib/orthoses/active_record/enum.rb +77 -0
- data/lib/orthoses/active_record/scope.rb +63 -0
- data/lib/orthoses/active_record.rb +3 -1
- data/lib/orthoses/active_support/class_attribute.rb +12 -12
- data/lib/orthoses/active_support/configurable.rb +36 -0
- data/lib/orthoses/active_support/delegation.rb +14 -14
- data/lib/orthoses/active_support/mattr_accessor.rb +8 -8
- data/lib/orthoses/active_support/time_with_zone.rb +22 -9
- data/lib/orthoses/active_support.rb +1 -4
- data/lib/orthoses/rails/version.rb +1 -1
- data/lib/orthoses/rails.rb +0 -1
- data/orthoses-rails.gemspec +1 -1
- metadata +22 -89
- data/examples/rails/known_sig/action_cable/connection/test_cookie_jar.rbs +0 -2
- data/examples/rails/known_sig/action_controller/metal.rbs +0 -4
- data/examples/rails/known_sig/action_dispatch/cookies/cookie_jar.rbs +0 -3
- data/examples/rails/known_sig/action_dispatch/response.rbs +0 -4
- data/examples/rails/patch/drb/drb_undumped.rbs +0 -2
- data/examples/rails/patch/drb.rbs +0 -2
- data/examples/rails/patch/erubi/engine.rbs +0 -4
- data/examples/rails/patch/erubi.rbs +0 -2
- data/examples/rails/patch/minitest/kernel.rbs +0 -44
- data/examples/rails/patch/minitest/minitest/abstract_reporter.rbs +0 -49
- data/examples/rails/patch/minitest/minitest/assertion.rbs +0 -16
- data/examples/rails/patch/minitest/minitest/assertions.rbs +0 -545
- data/examples/rails/patch/minitest/minitest/backtrace_filter.rbs +0 -16
- data/examples/rails/patch/minitest/minitest/bench_spec.rbs +0 -101
- data/examples/rails/patch/minitest/minitest/benchmark.rbs +0 -258
- data/examples/rails/patch/minitest/minitest/composite_reporter.rbs +0 -25
- data/examples/rails/patch/minitest/minitest/expectations.rbs +0 -21
- data/examples/rails/patch/minitest/minitest/guard.rbs +0 -64
- data/examples/rails/patch/minitest/minitest/mock.rbs +0 -60
- data/examples/rails/patch/minitest/minitest/parallel/executor.rbs +0 -42
- data/examples/rails/patch/minitest/minitest/parallel/test/class_methods.rbs +0 -6
- data/examples/rails/patch/minitest/minitest/parallel/test.rbs +0 -3
- data/examples/rails/patch/minitest/minitest/parallel.rbs +0 -2
- data/examples/rails/patch/minitest/minitest/pride_io.rbs +0 -54
- data/examples/rails/patch/minitest/minitest/pride_lol.rbs +0 -17
- data/examples/rails/patch/minitest/minitest/progress_reporter.rbs +0 -11
- data/examples/rails/patch/minitest/minitest/reportable.rbs +0 -51
- data/examples/rails/patch/minitest/minitest/reporter.rbs +0 -5
- data/examples/rails/patch/minitest/minitest/result.rbs +0 -28
- data/examples/rails/patch/minitest/minitest/runnable.rbs +0 -131
- data/examples/rails/patch/minitest/minitest/skip.rbs +0 -6
- data/examples/rails/patch/minitest/minitest/spec/dsl/instance_methods.rbs +0 -48
- data/examples/rails/patch/minitest/minitest/spec/dsl.rbs +0 -125
- data/examples/rails/patch/minitest/minitest/spec.rbs +0 -10
- data/examples/rails/patch/minitest/minitest/statistics_reporter.rbs +0 -76
- data/examples/rails/patch/minitest/minitest/summary_reporter.rbs +0 -26
- data/examples/rails/patch/minitest/minitest/test/lifecycle_hooks.rbs +0 -92
- data/examples/rails/patch/minitest/minitest/test.rbs +0 -76
- data/examples/rails/patch/minitest/minitest/unexpected_error.rbs +0 -10
- data/examples/rails/patch/minitest/minitest/unit/test_case.rbs +0 -3
- data/examples/rails/patch/minitest/minitest/unit.rbs +0 -5
- data/examples/rails/patch/minitest/minitest.rbs +0 -966
- data/examples/rails/patch/pg/simple_decoder.rbs +0 -4
- data/examples/rails/patch/pg.rbs +0 -2
- data/examples/rails/patch/qc/queue.rbs +0 -2
- data/examples/rails/patch/qc.rbs +0 -2
- data/examples/rails/patch/que/job.rbs +0 -2
- data/examples/rails/patch/que.rbs +0 -2
- data/examples/rails/patch/rack/cache/entity_store.rbs +0 -2
- data/examples/rails/patch/rack/cache/meta_store.rbs +0 -2
- data/examples/rails/patch/rack/cache.rbs +0 -2
- data/examples/rails/patch/rack/session/dalli.rbs +0 -2
- data/examples/rails/patch/rack/session.rbs +0 -2
- data/examples/rails/patch/rboc.rbs +0 -2
- data/examples/rails/patch/rdoc/generator/sdoc.rbs +0 -3
- data/examples/rails/patch/rdoc/generator.rbs +0 -2
- data/examples/rails/patch/rdoc/task.rbs +0 -2
- data/examples/rails/patch/ripper.rbs +0 -2
- data/examples/rails/patch/sidekiq/worker.rbs +0 -2
- data/examples/rails/patch/sidekiq.rbs +0 -2
- data/examples/rails/patch/sneakers/worker.rbs +0 -2
- data/examples/rails/patch/sneakers.rbs +0 -2
- data/examples/rails/patch/sucker_punch/job.rbs +0 -2
- data/examples/rails/patch/sucker_punch.rbs +0 -2
- data/examples/rails/patch/thor/actions/create_file.rbs +0 -2
- data/examples/rails/patch/thor/actions.rbs +0 -2
- data/examples/rails/patch/thor/error.rbs +0 -2
- data/examples/rails/patch/thor/group.rbs +0 -2
- data/examples/rails/patch/thor.rbs +0 -2
- data/lib/orthoses/active_model/known_sig/7.0/serialization.rbs +0 -4
- data/lib/orthoses/active_model/known_sig/7.0/validations.rbs +0 -4
- data/lib/orthoses/active_model/known_sig.rb +0 -21
- data/lib/orthoses/active_record/known_sig/6.0/result.rbs +0 -5
- data/lib/orthoses/active_record/known_sig/6.1/result.rbs +0 -5
- data/lib/orthoses/active_record/known_sig/7.0/encryption/context.rbs +0 -9
- data/lib/orthoses/active_record/known_sig/7.0/result.rbs +0 -5
- data/lib/orthoses/active_record/known_sig.rb +0 -21
- data/lib/orthoses/active_support/concern.rb +0 -32
- data/lib/orthoses/active_support/known_sig/7.0/active_support/callbacks/callback_chain.rbs +0 -9
- data/lib/orthoses/active_support/known_sig/7.0/active_support/hash_with_indifferent_access.rbs +0 -6
- data/lib/orthoses/active_support/known_sig/7.0/hash_with_indifferent_access.rbs +0 -2
- data/lib/orthoses/active_support/known_sig/7.0/time.rbs +0 -68
- data/lib/orthoses/active_support/known_sig.rb +0 -21
- 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.
|
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
|
@@ -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.
|
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.
|
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:
|
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
|
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
|
-
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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/
|
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
|
data/lib/orthoses/rails.rb
CHANGED
data/orthoses-rails.gemspec
CHANGED