rbs_rails 0.2.0 → 0.3.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/Gemfile +2 -2
- data/README.md +19 -1
- data/Rakefile +5 -1
- data/Steepfile +2 -0
- data/assets/sig/action_controller.rbs +16 -11
- data/assets/sig/action_mailer.rbs +6 -3
- data/assets/sig/active_record.rbs +7 -0
- data/assets/sig/capybara.rbs +14 -0
- data/assets/sig/concurrent.rbs +4 -0
- data/assets/sig/erb.rbs +4 -0
- data/assets/sig/erubi.rbs +4 -0
- data/assets/sig/generated/actionpack.rbs +11677 -0
- data/assets/sig/generated/actionview.rbs +10491 -0
- data/assets/sig/generated/activemodel.rbs +3591 -3329
- data/assets/sig/generated/activerecord-meta-programming.rbs +98 -0
- data/assets/sig/generated/activerecord.rbs +24023 -0
- data/assets/sig/generated/activesupport.rbs +9085 -8358
- data/assets/sig/generated/railties.rbs +4647 -0
- data/assets/sig/i18n.rbs +4 -0
- data/assets/sig/minitest.rbs +12 -1
- data/assets/sig/racc.rbs +4 -0
- data/assets/sig/rack-test.rbs +6 -0
- data/assets/sig/rack.rbs +46 -0
- data/assets/sig/rails.rbs +8 -5
- data/assets/sig/rdoc.rbs +9 -0
- data/assets/sig/stdlib.rbs +15 -5
- data/assets/sig/thor.rbs +12 -0
- data/assets/sig/tzinfo.rbs +4 -0
- data/bin/add-type-params.rb +32 -13
- data/bin/postprocess.rb +128 -0
- data/bin/rbs +3 -0
- data/bin/rbs-prototype-rb.rb +142 -0
- data/bin/to-ascii.rb +5 -0
- data/lib/rbs_rails/active_record.rb +33 -17
- data/lib/rbs_rails/version.rb +1 -1
- data/sig/rbs_rails/active_record.rbs +4 -4
- metadata +26 -8
- data/assets/sig/action_view.rbs +0 -3
- data/bin/merge-duplicate-decls.rb +0 -30
data/assets/sig/i18n.rbs
ADDED
data/assets/sig/minitest.rbs
CHANGED
data/assets/sig/racc.rbs
ADDED
data/assets/sig/rack.rbs
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Rack
|
2
|
+
class Server
|
3
|
+
end
|
4
|
+
|
5
|
+
class Response
|
6
|
+
module Helpers
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Request
|
11
|
+
module Helpers
|
12
|
+
end
|
13
|
+
|
14
|
+
module Env
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Session
|
19
|
+
module Abstract
|
20
|
+
class SessionHash
|
21
|
+
end
|
22
|
+
|
23
|
+
class PersistedSecure
|
24
|
+
class SecureSessionHash
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Persisted
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class SessionId
|
33
|
+
end
|
34
|
+
|
35
|
+
class Dalli
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Cache
|
40
|
+
class MetaStore
|
41
|
+
end
|
42
|
+
|
43
|
+
class EntityStore
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/assets/sig/rails.rbs
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
module Rails
|
2
|
-
def self.
|
3
|
-
|
2
|
+
overload def self.env: () -> ActiveSupport::StringInquirer
|
3
|
+
|
4
|
+
module Dom
|
5
|
+
module Testing
|
6
|
+
module Assertions
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
4
10
|
end
|
5
11
|
|
6
12
|
class Rails::Application
|
7
13
|
def routes: () -> untyped
|
8
14
|
end
|
9
|
-
|
10
|
-
class Rails::Railtie
|
11
|
-
end
|
data/assets/sig/rdoc.rbs
ADDED
data/assets/sig/stdlib.rbs
CHANGED
@@ -1,14 +1,24 @@
|
|
1
|
-
|
1
|
+
module DRb
|
2
2
|
end
|
3
3
|
|
4
|
-
|
4
|
+
module DRb::DRbUndumped
|
5
5
|
end
|
6
6
|
|
7
|
-
module
|
7
|
+
module TSort
|
8
8
|
end
|
9
9
|
|
10
|
-
|
10
|
+
class SimpleDelegator
|
11
11
|
end
|
12
12
|
|
13
|
-
module
|
13
|
+
module Gem
|
14
|
+
class Version
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module OpenSSL
|
19
|
+
class Cipher
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module FileUtils
|
14
24
|
end
|
data/assets/sig/thor.rbs
ADDED
data/bin/add-type-params.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
1
3
|
require 'rbs'
|
2
|
-
rbs = ARGF.read
|
3
|
-
decls = RBS::Parser.parse_signature(rbs)
|
4
4
|
|
5
5
|
def args(n)
|
6
6
|
(:T..).take(n)
|
7
7
|
end
|
8
8
|
|
9
9
|
def env
|
10
|
-
@env ||=
|
10
|
+
@env ||= begin
|
11
11
|
loader = RBS::EnvironmentLoader.new()
|
12
|
-
|
12
|
+
RBS::Environment.from_loader(loader).resolve_type_names
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -17,7 +17,7 @@ def apply_to_superclass(decl)
|
|
17
17
|
return unless decl.super_class
|
18
18
|
|
19
19
|
name = decl.super_class.name
|
20
|
-
type = env.
|
20
|
+
type = env.class_decls[name] || env.class_decls[name.absolute!]
|
21
21
|
return unless type
|
22
22
|
return if type.type_params.empty?
|
23
23
|
|
@@ -32,12 +32,21 @@ def apply_to_superclass(decl)
|
|
32
32
|
decl.instance_variable_set(:@type_params, type_params)
|
33
33
|
end
|
34
34
|
|
35
|
+
def apply_to_itself(decl)
|
36
|
+
name = decl.name
|
37
|
+
type = env.class_decls[name] || env.class_decls[name.absolute!]
|
38
|
+
return unless type
|
39
|
+
return if type.type_params.empty?
|
40
|
+
|
41
|
+
decl.instance_variable_set(:@type_params, type.type_params.dup)
|
42
|
+
end
|
43
|
+
|
35
44
|
def apply_to_includes(decl)
|
36
45
|
decl.members.each do |member|
|
37
46
|
next unless member.is_a?(RBS::AST::Members::Mixin)
|
38
47
|
|
39
48
|
name = member.name
|
40
|
-
type = env.
|
49
|
+
type = env.class_decls[name] || env.class_decls[name.absolute!]
|
41
50
|
next unless type
|
42
51
|
next if type.type_params.empty?
|
43
52
|
|
@@ -46,14 +55,24 @@ def apply_to_includes(decl)
|
|
46
55
|
end
|
47
56
|
end
|
48
57
|
|
49
|
-
decls
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
def analyze(decls)
|
59
|
+
decls.each do |decl|
|
60
|
+
case decl
|
61
|
+
when RBS::AST::Declarations::Class
|
62
|
+
apply_to_itself(decl)
|
63
|
+
apply_to_superclass(decl)
|
64
|
+
apply_to_includes(decl)
|
65
|
+
analyze(decl.members)
|
66
|
+
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
|
67
|
+
apply_to_itself(decl)
|
68
|
+
apply_to_includes(decl)
|
69
|
+
analyze(decl.members)
|
70
|
+
end
|
56
71
|
end
|
57
72
|
end
|
58
73
|
|
74
|
+
rbs = ARGF.read
|
75
|
+
decls = RBS::Parser.parse_signature(rbs)
|
76
|
+
analyze(decls)
|
77
|
+
|
59
78
|
puts RBS::Writer.new(out: $stdout).write(decls)
|
data/bin/postprocess.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
# TODO: Expose me to user
|
4
|
+
|
5
|
+
require 'rbs'
|
6
|
+
require 'rbs/cli'
|
7
|
+
require 'optparse'
|
8
|
+
|
9
|
+
def env(options:)
|
10
|
+
loader = RBS::EnvironmentLoader.new()
|
11
|
+
options.setup(loader)
|
12
|
+
RBS::Environment.from_loader(loader).resolve_type_names
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_option(argv)
|
16
|
+
opt = OptionParser.new
|
17
|
+
options = RBS::CLI::LibraryOptions.new
|
18
|
+
cli = RBS::CLI.new(stdout: nil, stderr: nil)
|
19
|
+
cli.library_parse(opt, options: options)
|
20
|
+
|
21
|
+
return opt.parse(argv), options
|
22
|
+
end
|
23
|
+
|
24
|
+
class FileMatcher
|
25
|
+
def initialize(targets:)
|
26
|
+
base_dir = Dir.pwd
|
27
|
+
@targets = targets + targets.map { |t| File.expand_path(t, base_dir) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def match?(fname)
|
31
|
+
@targets.any? { |t| fname.start_with?(t) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_method_name(concern)
|
36
|
+
RBS::TypeName.new(namespace: concern.name.to_namespace, name: :ClassMethods)
|
37
|
+
end
|
38
|
+
|
39
|
+
def process(decl, env:, builder:, update_targets:)
|
40
|
+
concerns = decl.members.select do |m|
|
41
|
+
next false unless m.is_a?(RBS::AST::Members::Include)
|
42
|
+
next false unless m.name.kind == :class
|
43
|
+
|
44
|
+
mod_entry = env.class_decls[m.name]
|
45
|
+
unless mod_entry
|
46
|
+
warn "unknown type: #{m.name}"
|
47
|
+
next false
|
48
|
+
end
|
49
|
+
|
50
|
+
a = builder.singleton_ancestors(m.name)
|
51
|
+
a.ancestors.any? { |ancestor| ancestor.name.to_s == '::ActiveSupport::Concern' }
|
52
|
+
end
|
53
|
+
|
54
|
+
concerns.each do |concern|
|
55
|
+
class_methods_name = class_method_name(concern)
|
56
|
+
class_methods_type = env.class_decls[class_methods_name]
|
57
|
+
next unless class_methods_type
|
58
|
+
|
59
|
+
# Skip if the decl already extend ClassMethods
|
60
|
+
a = builder.singleton_ancestors(decl.name)
|
61
|
+
next if a.ancestors.any? { |ancestor| ancestor.name == class_methods_name }
|
62
|
+
|
63
|
+
# TODO: Insert `extend class_methods_name` to decl
|
64
|
+
update_targets << [decl, concern]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def each_decl_descendant(decl:, path: [], &block)
|
69
|
+
return unless decl.is_a?(RBS::AST::Declarations::Class) || decl.is_a?(RBS::AST::Declarations::Module)
|
70
|
+
|
71
|
+
block.call(decl: decl, path: path)
|
72
|
+
path = [*path, decl]
|
73
|
+
decl.each_decl do |child|
|
74
|
+
each_decl_descendant(decl: child, path: path, &block)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def may_eql_member?(a, b)
|
79
|
+
a.name.to_s.split('::').last == b.name.to_s.split('::').last
|
80
|
+
end
|
81
|
+
|
82
|
+
def update!(update_targets:)
|
83
|
+
update_targets.group_by { |decl, _concern| decl.location.name }.each do |fname, target_decls|
|
84
|
+
tree = RBS::Parser.parse_signature(File.read(fname))
|
85
|
+
target_decls.each do |target_decl, concern|
|
86
|
+
catch(:break) do
|
87
|
+
tree.each do |node|
|
88
|
+
each_decl_descendant(decl: node) do |decl:, path:|
|
89
|
+
next unless [relative = [*path, decl].map { |p| p.name.to_s }.join('::'), '::' + relative].include?(target_decl.name.to_s)
|
90
|
+
|
91
|
+
idx = decl.members.index { |m| may_eql_member?(m, concern) } || -1
|
92
|
+
extend = RBS::AST::Members::Extend.new(name: class_method_name(concern), args: [], annotations: [], location: nil, comment: nil)
|
93
|
+
decl.members.insert(idx + 1, extend)
|
94
|
+
throw :break
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
File.open(fname, 'w') do |f|
|
101
|
+
RBS::Writer.new(out: f).write(tree)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def run(argv)
|
107
|
+
targets, options = parse_option(argv)
|
108
|
+
env = env(options: options)
|
109
|
+
builder = RBS::DefinitionBuilder.new(env: env)
|
110
|
+
matcher = FileMatcher.new(targets: targets)
|
111
|
+
|
112
|
+
update_targets = []
|
113
|
+
|
114
|
+
env.class_decls.each do |_name, entry|
|
115
|
+
entry.decls.each do |d|
|
116
|
+
decl = d.decl
|
117
|
+
loc = decl.location
|
118
|
+
fname = loc.name
|
119
|
+
next unless matcher.match?(fname)
|
120
|
+
|
121
|
+
process(decl, env: env, builder: builder, update_targets: update_targets)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
update!(update_targets: update_targets)
|
126
|
+
end
|
127
|
+
|
128
|
+
run(ARGV)
|
data/bin/rbs
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
require 'rbs'
|
4
|
+
require 'rbs/cli'
|
5
|
+
|
6
|
+
using Module.new {
|
7
|
+
refine(Object) do
|
8
|
+
def const_name(node)
|
9
|
+
case node.type
|
10
|
+
when :CONST
|
11
|
+
node.children[0]
|
12
|
+
when :COLON2
|
13
|
+
base, name = node.children
|
14
|
+
base = const_name(base)
|
15
|
+
return unless base
|
16
|
+
"#{base}::#{name}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_class_methods(node, decls:, comments:, singleton:)
|
21
|
+
return false unless node.type == :ITER
|
22
|
+
|
23
|
+
fcall = node.children[0]
|
24
|
+
return false unless fcall.children[0] == :class_methods
|
25
|
+
|
26
|
+
name = RBS::TypeName.new(name: :ClassMethods, namespace: RBS::Namespace.empty)
|
27
|
+
mod = RBS::AST::Declarations::Module.new(
|
28
|
+
name: name,
|
29
|
+
type_params: RBS::AST::Declarations::ModuleTypeParams.empty,
|
30
|
+
self_types: [],
|
31
|
+
members: [],
|
32
|
+
annotations: [],
|
33
|
+
location: nil,
|
34
|
+
comment: comments[node.first_lineno - 1]
|
35
|
+
)
|
36
|
+
|
37
|
+
decls.push mod
|
38
|
+
|
39
|
+
each_node [node.children[1]] do |child|
|
40
|
+
process child, decls: mod.members, comments: comments, singleton: false
|
41
|
+
end
|
42
|
+
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def process_struct_new(node, decls:, comments:, singleton:)
|
47
|
+
return unless node.type == :CDECL
|
48
|
+
|
49
|
+
name, *_, rhs = node.children
|
50
|
+
fields, body = struct_new(rhs)
|
51
|
+
return unless fields
|
52
|
+
|
53
|
+
type_name = RBS::TypeName.new(name: name, namespace: RBS::Namespace.empty)
|
54
|
+
kls = RBS::AST::Declarations::Class.new(
|
55
|
+
name: type_name,
|
56
|
+
super_class: struct_as_superclass,
|
57
|
+
type_params: RBS::AST::Declarations::ModuleTypeParams.empty,
|
58
|
+
members: [],
|
59
|
+
annotations: [],
|
60
|
+
location: nil,
|
61
|
+
comment: comments[node.first_lineno - 1],
|
62
|
+
)
|
63
|
+
decls.push kls
|
64
|
+
|
65
|
+
fields.children.compact.each do |f|
|
66
|
+
case f.type
|
67
|
+
when :LIT, :STR
|
68
|
+
kls.members << RBS::AST::Members::AttrAccessor.new(
|
69
|
+
name: f.children.first,
|
70
|
+
type: untyped,
|
71
|
+
ivar_name: false,
|
72
|
+
annotations: [],
|
73
|
+
location: nil,
|
74
|
+
comment: nil,
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
if body
|
80
|
+
each_node [body] do |child|
|
81
|
+
process child, decls: kls.members, comments: comments, singleton: false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
def class_new_method_to_type(node)
|
89
|
+
case node.type
|
90
|
+
when :CALL
|
91
|
+
recv, name, _args = node.children
|
92
|
+
return unless name == :new
|
93
|
+
|
94
|
+
klass = const_name(recv)
|
95
|
+
return unless klass
|
96
|
+
|
97
|
+
type_name = RBS::TypeName.new(name: klass, namespace: RBS::Namespace.empty)
|
98
|
+
RBS::Types::ClassInstance.new(name: type_name, args: [], location: nil)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def struct_new(node)
|
103
|
+
case node.type
|
104
|
+
when :CALL
|
105
|
+
# ok
|
106
|
+
when :ITER
|
107
|
+
call, block = node.children
|
108
|
+
return struct_new(call)&.tap do |r|
|
109
|
+
r << block
|
110
|
+
end
|
111
|
+
else
|
112
|
+
return
|
113
|
+
end
|
114
|
+
|
115
|
+
recv, method_name, args = node.children
|
116
|
+
return unless method_name == :new
|
117
|
+
return unless recv.type == :CONST || recv.type == :COLON3
|
118
|
+
return unless recv.children.first == :Struct
|
119
|
+
|
120
|
+
[args]
|
121
|
+
end
|
122
|
+
|
123
|
+
def struct_as_superclass
|
124
|
+
name = RBS::TypeName.new(name: 'Struct', namespace: RBS::Namespace.root)
|
125
|
+
RBS::AST::Declarations::Class::Super.new(name: name, args: ['untyped'])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
}
|
129
|
+
|
130
|
+
module PrototypeExt
|
131
|
+
def process(...)
|
132
|
+
process_class_methods(...) || process_struct_new(...) || super
|
133
|
+
end
|
134
|
+
|
135
|
+
def literal_to_type(node)
|
136
|
+
class_new_method_to_type(node) || super
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
RBS::Prototype::RB.prepend PrototypeExt
|
141
|
+
|
142
|
+
RBS::CLI.new(stdout: STDOUT, stderr: STDERR).run(ARGV.dup)
|