rbs 0.4.0 → 0.5.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/.github/workflows/ruby.yml +7 -1
- data/.gitignore +1 -1
- data/CHANGELOG.md +7 -0
- data/Gemfile +12 -0
- data/README.md +86 -47
- data/Rakefile +54 -21
- data/bin/rbs-prof +9 -0
- data/bin/run_in_md.rb +49 -0
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +62 -7
- data/lib/rbs/ast/members.rb +41 -17
- data/lib/rbs/cli.rb +299 -121
- data/lib/rbs/constant.rb +4 -4
- data/lib/rbs/constant_table.rb +50 -44
- data/lib/rbs/definition.rb +175 -59
- data/lib/rbs/definition_builder.rb +647 -603
- data/lib/rbs/environment.rb +338 -209
- data/lib/rbs/environment_walker.rb +14 -23
- data/lib/rbs/errors.rb +141 -3
- data/lib/rbs/parser.y +14 -9
- data/lib/rbs/prototype/rb.rb +100 -112
- data/lib/rbs/prototype/rbi.rb +4 -2
- data/lib/rbs/prototype/runtime.rb +10 -6
- data/lib/rbs/substitution.rb +8 -1
- data/lib/rbs/test/hook.rb +2 -2
- data/lib/rbs/test/setup.rb +3 -1
- data/lib/rbs/test/test_helper.rb +2 -5
- data/lib/rbs/test/type_check.rb +1 -2
- data/lib/rbs/type_name_resolver.rb +58 -0
- data/lib/rbs/types.rb +94 -2
- data/lib/rbs/validator.rb +51 -0
- data/lib/rbs/variance_calculator.rb +12 -2
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +125 -89
- data/rbs.gemspec +0 -10
- data/schema/decls.json +15 -0
- data/schema/members.json +3 -0
- data/stdlib/benchmark/benchmark.rbs +151 -151
- data/stdlib/builtin/enumerable.rbs +1 -1
- data/stdlib/builtin/file.rbs +0 -3
- data/stdlib/builtin/io.rbs +4 -4
- data/stdlib/builtin/thread.rbs +2 -2
- data/stdlib/csv/csv.rbs +4 -6
- data/stdlib/fiber/fiber.rbs +1 -1
- data/stdlib/json/json.rbs +1 -1
- data/stdlib/mutex_m/mutex_m.rbs +77 -0
- data/stdlib/pathname/pathname.rbs +6 -6
- data/stdlib/prime/integer-extension.rbs +1 -1
- data/stdlib/prime/prime.rbs +44 -44
- data/stdlib/tmpdir/tmpdir.rbs +1 -1
- metadata +8 -129
data/lib/rbs/ast/members.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
module RBS
|
2
2
|
module AST
|
3
3
|
module Members
|
4
|
-
class
|
4
|
+
class Base
|
5
|
+
end
|
6
|
+
|
7
|
+
class MethodDefinition < Base
|
5
8
|
attr_reader :name
|
6
9
|
attr_reader :kind
|
7
10
|
attr_reader :types
|
@@ -9,8 +12,9 @@ module RBS
|
|
9
12
|
attr_reader :location
|
10
13
|
attr_reader :comment
|
11
14
|
attr_reader :attributes
|
15
|
+
attr_reader :overload
|
12
16
|
|
13
|
-
def initialize(name:, kind:, types:, annotations:, location:, comment:, attributes:)
|
17
|
+
def initialize(name:, kind:, types:, annotations:, location:, comment:, attributes:, overload:)
|
14
18
|
@name = name
|
15
19
|
@kind = kind
|
16
20
|
@types = types
|
@@ -18,6 +22,7 @@ module RBS
|
|
18
22
|
@location = location
|
19
23
|
@comment = comment
|
20
24
|
@attributes = attributes
|
25
|
+
@overload = overload
|
21
26
|
end
|
22
27
|
|
23
28
|
def ==(other)
|
@@ -25,13 +30,14 @@ module RBS
|
|
25
30
|
other.name == name &&
|
26
31
|
other.kind == kind &&
|
27
32
|
other.types == types &&
|
28
|
-
other.attributes == attributes
|
33
|
+
other.attributes == attributes &&
|
34
|
+
other.overload == overload
|
29
35
|
end
|
30
36
|
|
31
37
|
alias eql? ==
|
32
38
|
|
33
39
|
def hash
|
34
|
-
self.class.hash ^ name.hash ^ kind.hash ^ types.hash ^ attributes.hash
|
40
|
+
self.class.hash ^ name.hash ^ kind.hash ^ types.hash ^ attributes.hash ^ overload.hash
|
35
41
|
end
|
36
42
|
|
37
43
|
def instance?
|
@@ -42,6 +48,23 @@ module RBS
|
|
42
48
|
kind == :singleton || kind == :singleton_instance
|
43
49
|
end
|
44
50
|
|
51
|
+
def overload?
|
52
|
+
overload
|
53
|
+
end
|
54
|
+
|
55
|
+
def update(name: self.name, kind: self.kind, types: self.types, annotations: self.annotations, location: self.location, comment: self.comment, attributes: self.attributes, overload: self.overload)
|
56
|
+
self.class.new(
|
57
|
+
name: name,
|
58
|
+
kind: kind,
|
59
|
+
types: types,
|
60
|
+
annotations: annotations,
|
61
|
+
location: location,
|
62
|
+
comment: comment,
|
63
|
+
attributes: attributes,
|
64
|
+
overload: overload
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
45
68
|
def to_json(*a)
|
46
69
|
{
|
47
70
|
member: :method_definition,
|
@@ -50,7 +73,8 @@ module RBS
|
|
50
73
|
annotations: annotations,
|
51
74
|
location: location,
|
52
75
|
comment: comment,
|
53
|
-
attributes: attributes
|
76
|
+
attributes: attributes,
|
77
|
+
overload: overload
|
54
78
|
}.to_json(*a)
|
55
79
|
end
|
56
80
|
end
|
@@ -79,7 +103,7 @@ module RBS
|
|
79
103
|
end
|
80
104
|
end
|
81
105
|
|
82
|
-
class InstanceVariable
|
106
|
+
class InstanceVariable < Base
|
83
107
|
include Var
|
84
108
|
|
85
109
|
def to_json(*a)
|
@@ -93,7 +117,7 @@ module RBS
|
|
93
117
|
end
|
94
118
|
end
|
95
119
|
|
96
|
-
class ClassInstanceVariable
|
120
|
+
class ClassInstanceVariable < Base
|
97
121
|
include Var
|
98
122
|
|
99
123
|
def to_json(*a)
|
@@ -107,7 +131,7 @@ module RBS
|
|
107
131
|
end
|
108
132
|
end
|
109
133
|
|
110
|
-
class ClassVariable
|
134
|
+
class ClassVariable < Base
|
111
135
|
include Var
|
112
136
|
|
113
137
|
def to_json(*a)
|
@@ -149,7 +173,7 @@ module RBS
|
|
149
173
|
end
|
150
174
|
end
|
151
175
|
|
152
|
-
class Include
|
176
|
+
class Include < Base
|
153
177
|
include Mixin
|
154
178
|
|
155
179
|
def to_json(*a)
|
@@ -164,7 +188,7 @@ module RBS
|
|
164
188
|
end
|
165
189
|
end
|
166
190
|
|
167
|
-
class Extend
|
191
|
+
class Extend < Base
|
168
192
|
include Mixin
|
169
193
|
|
170
194
|
def to_json(*a)
|
@@ -179,7 +203,7 @@ module RBS
|
|
179
203
|
end
|
180
204
|
end
|
181
205
|
|
182
|
-
class Prepend
|
206
|
+
class Prepend < Base
|
183
207
|
include Mixin
|
184
208
|
|
185
209
|
def to_json(*a)
|
@@ -225,7 +249,7 @@ module RBS
|
|
225
249
|
end
|
226
250
|
end
|
227
251
|
|
228
|
-
class AttrReader
|
252
|
+
class AttrReader < Base
|
229
253
|
include Attribute
|
230
254
|
|
231
255
|
def to_json(*a)
|
@@ -241,7 +265,7 @@ module RBS
|
|
241
265
|
end
|
242
266
|
end
|
243
267
|
|
244
|
-
class AttrAccessor
|
268
|
+
class AttrAccessor < Base
|
245
269
|
include Attribute
|
246
270
|
|
247
271
|
def to_json(*a)
|
@@ -257,7 +281,7 @@ module RBS
|
|
257
281
|
end
|
258
282
|
end
|
259
283
|
|
260
|
-
class AttrWriter
|
284
|
+
class AttrWriter < Base
|
261
285
|
include Attribute
|
262
286
|
|
263
287
|
def to_json(*a)
|
@@ -291,7 +315,7 @@ module RBS
|
|
291
315
|
end
|
292
316
|
end
|
293
317
|
|
294
|
-
class Public
|
318
|
+
class Public < Base
|
295
319
|
include LocationOnly
|
296
320
|
|
297
321
|
def to_json(*a)
|
@@ -299,7 +323,7 @@ module RBS
|
|
299
323
|
end
|
300
324
|
end
|
301
325
|
|
302
|
-
class Private
|
326
|
+
class Private < Base
|
303
327
|
include LocationOnly
|
304
328
|
|
305
329
|
def to_json(*a)
|
@@ -307,7 +331,7 @@ module RBS
|
|
307
331
|
end
|
308
332
|
end
|
309
333
|
|
310
|
-
class Alias
|
334
|
+
class Alias < Base
|
311
335
|
attr_reader :new_name
|
312
336
|
attr_reader :old_name
|
313
337
|
attr_reader :kind
|
data/lib/rbs/cli.rb
CHANGED
@@ -36,18 +36,18 @@ module RBS
|
|
36
36
|
@stderr = stderr
|
37
37
|
end
|
38
38
|
|
39
|
-
COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :
|
39
|
+
COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse]
|
40
40
|
|
41
41
|
def library_parse(opts, options:)
|
42
|
-
opts.on("-r LIBRARY") do |lib|
|
42
|
+
opts.on("-r LIBRARY", "Load RBS files of the library") do |lib|
|
43
43
|
options.libs << lib
|
44
44
|
end
|
45
45
|
|
46
|
-
opts.on("-I DIR") do |dir|
|
46
|
+
opts.on("-I DIR", "Load RBS files from the directory") do |dir|
|
47
47
|
options.dirs << dir
|
48
48
|
end
|
49
49
|
|
50
|
-
opts.on("--no-stdlib") do
|
50
|
+
opts.on("--no-stdlib", "Skip loading standard library signatures") do
|
51
51
|
options.no_stdlib = true
|
52
52
|
end
|
53
53
|
|
@@ -55,11 +55,11 @@ module RBS
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def parse_logging_options(opts)
|
58
|
-
opts.on("--log-level
|
58
|
+
opts.on("--log-level LEVEL", "Specify log level (defaults to `warn`)") do |level|
|
59
59
|
RBS.logger_level = level
|
60
60
|
end
|
61
61
|
|
62
|
-
opts.on("--log-output
|
62
|
+
opts.on("--log-output OUTPUT", "Specify the file to output log (defaults to stderr)") do |output|
|
63
63
|
RBS.logger_output = File.open(output, "a")
|
64
64
|
end
|
65
65
|
|
@@ -71,17 +71,24 @@ module RBS
|
|
71
71
|
|
72
72
|
opts = OptionParser.new
|
73
73
|
opts.banner = <<~USAGE
|
74
|
-
Usage: rbs [options]
|
75
|
-
|
74
|
+
Usage: rbs [options...] [command...]
|
75
|
+
|
76
|
+
Available commands: #{COMMANDS.join(", ")}, version, help.
|
77
|
+
|
78
|
+
Options:
|
76
79
|
USAGE
|
77
80
|
library_parse(opts, options: options)
|
78
81
|
parse_logging_options(opts)
|
82
|
+
opts.version = RBS::VERSION
|
79
83
|
|
80
84
|
opts.order!(args)
|
81
85
|
|
82
86
|
command = args.shift&.to_sym
|
83
87
|
|
84
|
-
|
88
|
+
case command
|
89
|
+
when :version
|
90
|
+
stdout.puts opts.ver
|
91
|
+
when *COMMANDS
|
85
92
|
__send__ :"run_#{command}", args, options
|
86
93
|
else
|
87
94
|
stdout.puts opts.help
|
@@ -89,101 +96,151 @@ module RBS
|
|
89
96
|
end
|
90
97
|
|
91
98
|
def run_ast(args, options)
|
92
|
-
|
99
|
+
OptionParser.new do |opts|
|
100
|
+
opts.banner = <<EOB
|
101
|
+
Usage: rbs ast [patterns...]
|
102
|
+
|
103
|
+
Print JSON AST of loaded environment.
|
104
|
+
You can specify patterns to filter declarations with the file names.
|
105
|
+
|
106
|
+
Examples:
|
107
|
+
|
108
|
+
$ rbs ast
|
109
|
+
$ rbs ast 'basic_object.rbs'
|
110
|
+
$ rbs -I ./sig ast ./sig
|
111
|
+
$ rbs -I ./sig ast '*/models/*.rbs'
|
112
|
+
EOB
|
113
|
+
end.order!(args)
|
93
114
|
|
115
|
+
patterns = args.map do |arg|
|
116
|
+
path = Pathname(arg)
|
117
|
+
if path.exist?
|
118
|
+
# Pathname means a directory or a file
|
119
|
+
path
|
120
|
+
else
|
121
|
+
# String means a `fnmatch` pattern
|
122
|
+
arg
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
loader = EnvironmentLoader.new()
|
94
127
|
options.setup(loader)
|
95
128
|
|
96
|
-
env = Environment.
|
97
|
-
|
129
|
+
env = Environment.from_loader(loader).resolve_type_names
|
130
|
+
|
131
|
+
decls = env.declarations.select do |decl|
|
132
|
+
name = decl.location.buffer.name
|
98
133
|
|
99
|
-
|
134
|
+
patterns.empty? || patterns.any? do |pat|
|
135
|
+
case pat
|
136
|
+
when Pathname
|
137
|
+
Pathname(name).ascend.any? {|p| p == pat }
|
138
|
+
when String
|
139
|
+
name.end_with?(pat) || File.fnmatch(pat, name, File::FNM_EXTGLOB)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
stdout.print JSON.generate(decls)
|
100
145
|
stdout.flush
|
101
146
|
end
|
102
147
|
|
103
148
|
def run_list(args, options)
|
104
|
-
list = []
|
149
|
+
list = Set[]
|
105
150
|
|
106
151
|
OptionParser.new do |opts|
|
107
|
-
opts.
|
108
|
-
|
109
|
-
|
152
|
+
opts.banner = <<EOB
|
153
|
+
Usage: rbs list [options...]
|
154
|
+
|
155
|
+
List classes, modules, and interfaces.
|
156
|
+
|
157
|
+
Examples:
|
158
|
+
|
159
|
+
$ rbs list
|
160
|
+
$ rbs list --class --module --interface
|
161
|
+
|
162
|
+
Options:
|
163
|
+
EOB
|
164
|
+
opts.on("--class", "List classes") { list << :class }
|
165
|
+
opts.on("--module", "List modules") { list << :module }
|
166
|
+
opts.on("--interface", "List interfaces") { list << :interface }
|
110
167
|
end.order!(args)
|
111
168
|
|
112
|
-
list.
|
169
|
+
list.merge([:class, :module, :interface]) if list.empty?
|
113
170
|
|
114
171
|
loader = EnvironmentLoader.new()
|
115
|
-
|
116
172
|
options.setup(loader)
|
117
173
|
|
118
|
-
env = Environment.
|
119
|
-
loader.load(env: env)
|
174
|
+
env = Environment.from_loader(loader).resolve_type_names
|
120
175
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
if list.include?(:interface)
|
133
|
-
stdout.puts "#{type_name} (interface)"
|
176
|
+
if list.include?(:class) || list.include?(:module)
|
177
|
+
env.class_decls.each do |name, entry|
|
178
|
+
case entry
|
179
|
+
when Environment::ModuleEntry
|
180
|
+
if list.include?(:module)
|
181
|
+
stdout.puts "#{name} (module)"
|
182
|
+
end
|
183
|
+
when Environment::ClassEntry
|
184
|
+
if list.include?(:class)
|
185
|
+
stdout.puts "#{name} (class)"
|
186
|
+
end
|
134
187
|
end
|
135
188
|
end
|
136
189
|
end
|
190
|
+
|
191
|
+
if list.include?(:interface)
|
192
|
+
env.interface_decls.each do |name, entry|
|
193
|
+
stdout.puts "#{name} (interface)"
|
194
|
+
end
|
195
|
+
end
|
137
196
|
end
|
138
197
|
|
139
198
|
def run_ancestors(args, options)
|
140
199
|
kind = :instance
|
141
200
|
|
142
201
|
OptionParser.new do |opts|
|
143
|
-
opts.
|
144
|
-
|
202
|
+
opts.banner = <<EOU
|
203
|
+
Usage: rbs ancestors [options...] [type_name]
|
204
|
+
|
205
|
+
Show ancestors of the given class or module.
|
206
|
+
|
207
|
+
Examples:
|
208
|
+
|
209
|
+
$ rbs ancestors --instance String
|
210
|
+
$ rbs ancestors --singleton Array
|
211
|
+
|
212
|
+
Options:
|
213
|
+
EOU
|
214
|
+
opts.on("--instance", "Ancestors of instance of the given type_name (default)") { kind = :instance }
|
215
|
+
opts.on("--singleton", "Ancestors of singleton of the given type_name") { kind = :singleton }
|
145
216
|
end.order!(args)
|
146
217
|
|
147
218
|
loader = EnvironmentLoader.new()
|
148
|
-
|
149
219
|
options.setup(loader)
|
150
220
|
|
151
|
-
env = Environment.
|
152
|
-
loader.load(env: env)
|
221
|
+
env = Environment.from_loader(loader).resolve_type_names
|
153
222
|
|
154
223
|
builder = DefinitionBuilder.new(env: env)
|
155
224
|
type_name = parse_type_name(args[0]).absolute!
|
156
225
|
|
157
|
-
if env.
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
Definition::Ancestor::Singleton.new(name: type_name)
|
165
|
-
end
|
166
|
-
|
167
|
-
ancestors = builder.build_ancestors(ancestor)
|
226
|
+
if env.class_decls.key?(type_name)
|
227
|
+
ancestors = case kind
|
228
|
+
when :instance
|
229
|
+
builder.instance_ancestors(type_name)
|
230
|
+
when :singleton
|
231
|
+
builder.singleton_ancestors(type_name)
|
232
|
+
end
|
168
233
|
|
169
|
-
ancestors.each do |ancestor|
|
234
|
+
ancestors.ancestors.each do |ancestor|
|
170
235
|
case ancestor
|
171
236
|
when Definition::Ancestor::Singleton
|
172
237
|
stdout.puts "singleton(#{ancestor.name})"
|
173
|
-
when Definition::Ancestor::ExtensionSingleton
|
174
|
-
stdout.puts "singleton(#{ancestor.name} (#{ancestor.extension_name}))"
|
175
238
|
when Definition::Ancestor::Instance
|
176
239
|
if ancestor.args.empty?
|
177
240
|
stdout.puts ancestor.name.to_s
|
178
241
|
else
|
179
242
|
stdout.puts "#{ancestor.name}[#{ancestor.args.join(", ")}]"
|
180
243
|
end
|
181
|
-
when Definition::Ancestor::ExtensionInstance
|
182
|
-
if ancestor.args.empty?
|
183
|
-
stdout.puts "#{ancestor.name} (#{ancestor.extension_name})"
|
184
|
-
else
|
185
|
-
stdout.puts "#{ancestor.name}[#{ancestor.args.join(", ")}] (#{ancestor.extension_name})"
|
186
|
-
end
|
187
244
|
end
|
188
245
|
end
|
189
246
|
else
|
@@ -196,10 +253,21 @@ module RBS
|
|
196
253
|
inherit = true
|
197
254
|
|
198
255
|
OptionParser.new do |opts|
|
199
|
-
opts.
|
200
|
-
|
201
|
-
|
202
|
-
|
256
|
+
opts.banner = <<EOU
|
257
|
+
Usage: rbs methods [options...] [type_name]
|
258
|
+
|
259
|
+
Show methods defined in the class or module.
|
260
|
+
|
261
|
+
Examples:
|
262
|
+
|
263
|
+
$ rbs methods --instance Kernel
|
264
|
+
$ rbs methods --singleton --no-inherit String
|
265
|
+
|
266
|
+
Options:
|
267
|
+
EOU
|
268
|
+
opts.on("--instance", "Show instance methods (default)") { kind = :instance }
|
269
|
+
opts.on("--singleton", "Show singleton methods") { kind = :singleton }
|
270
|
+
opts.on("--[no-]inherit", "Show methods defined in super class and mixed modules too") {|v| inherit = v }
|
203
271
|
end.order!(args)
|
204
272
|
|
205
273
|
unless args.size == 1
|
@@ -208,16 +276,14 @@ module RBS
|
|
208
276
|
end
|
209
277
|
|
210
278
|
loader = EnvironmentLoader.new()
|
211
|
-
|
212
279
|
options.setup(loader)
|
213
280
|
|
214
|
-
env = Environment.
|
215
|
-
loader.load(env: env)
|
281
|
+
env = Environment.from_loader(loader).resolve_type_names
|
216
282
|
|
217
283
|
builder = DefinitionBuilder.new(env: env)
|
218
284
|
type_name = parse_type_name(args[0]).absolute!
|
219
285
|
|
220
|
-
if env.
|
286
|
+
if env.class_decls.key?(type_name)
|
221
287
|
definition = case kind
|
222
288
|
when :instance
|
223
289
|
builder.build_instance(type_name)
|
@@ -227,7 +293,7 @@ module RBS
|
|
227
293
|
|
228
294
|
definition.methods.keys.sort.each do |name|
|
229
295
|
method = definition.methods[name]
|
230
|
-
if inherit || method.implemented_in ==
|
296
|
+
if inherit || method.implemented_in == type_name
|
231
297
|
stdout.puts "#{name} (#{method.accessibility})"
|
232
298
|
end
|
233
299
|
end
|
@@ -240,8 +306,20 @@ module RBS
|
|
240
306
|
kind = :instance
|
241
307
|
|
242
308
|
OptionParser.new do |opts|
|
243
|
-
opts.
|
244
|
-
|
309
|
+
opts.banner = <<EOU
|
310
|
+
Usage: rbs method [options...] [type_name] [method_name]
|
311
|
+
|
312
|
+
Show the information of the method specified by type_name and method_name.
|
313
|
+
|
314
|
+
Examples:
|
315
|
+
|
316
|
+
$ rbs method --instance Kernel puts
|
317
|
+
$ rbs method --singleton String try_convert
|
318
|
+
|
319
|
+
Options:
|
320
|
+
EOU
|
321
|
+
opts.on("--instance", "Show an instance method (default)") { kind = :instance }
|
322
|
+
opts.on("--singleton", "Show a singleton method") { kind = :singleton }
|
245
323
|
end.order!(args)
|
246
324
|
|
247
325
|
unless args.size == 2
|
@@ -250,17 +328,15 @@ module RBS
|
|
250
328
|
end
|
251
329
|
|
252
330
|
loader = EnvironmentLoader.new()
|
253
|
-
|
254
331
|
options.setup(loader)
|
255
332
|
|
256
|
-
env = Environment.
|
257
|
-
loader.load(env: env)
|
333
|
+
env = Environment.from_loader(loader).resolve_type_names
|
258
334
|
|
259
335
|
builder = DefinitionBuilder.new(env: env)
|
260
336
|
type_name = parse_type_name(args[0]).absolute!
|
261
337
|
method_name = args[1].to_sym
|
262
338
|
|
263
|
-
unless env.
|
339
|
+
unless env.class_decls.key?(type_name)
|
264
340
|
stdout.puts "Cannot find class: #{type_name}"
|
265
341
|
return
|
266
342
|
end
|
@@ -280,8 +356,8 @@ module RBS
|
|
280
356
|
end
|
281
357
|
|
282
358
|
stdout.puts "#{type_name}#{kind == :instance ? "#" : "."}#{method_name}"
|
283
|
-
stdout.puts " defined_in: #{method.defined_in
|
284
|
-
stdout.puts " implementation: #{method.implemented_in
|
359
|
+
stdout.puts " defined_in: #{method.defined_in}"
|
360
|
+
stdout.puts " implementation: #{method.implemented_in}"
|
285
361
|
stdout.puts " accessibility: #{method.accessibility}"
|
286
362
|
stdout.puts " types:"
|
287
363
|
separator = " "
|
@@ -292,46 +368,57 @@ module RBS
|
|
292
368
|
end
|
293
369
|
|
294
370
|
def run_validate(args, options)
|
371
|
+
OptionParser.new do |opts|
|
372
|
+
opts.banner = <<EOU
|
373
|
+
Usage: rbs validate
|
374
|
+
|
375
|
+
Validate RBS files. It ensures the type names in RBS files are present and the type applications have correct arity.
|
376
|
+
|
377
|
+
Examples:
|
378
|
+
|
379
|
+
$ rbs validate
|
380
|
+
EOU
|
381
|
+
end.parse!(args)
|
382
|
+
|
295
383
|
loader = EnvironmentLoader.new()
|
296
384
|
|
297
385
|
options.setup(loader)
|
298
386
|
|
299
|
-
env = Environment.
|
300
|
-
loader.load(env: env)
|
387
|
+
env = Environment.from_loader(loader).resolve_type_names
|
301
388
|
|
302
389
|
builder = DefinitionBuilder.new(env: env)
|
390
|
+
validator = Validator.new(env: env, resolver: TypeNameResolver.from_env(env))
|
303
391
|
|
304
|
-
env.
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
builder.build_singleton(decl.name.absolute!).each_type do |type|
|
312
|
-
env.validate type, namespace: Namespace.root
|
313
|
-
end
|
314
|
-
when AST::Declarations::Interface
|
315
|
-
stdout.puts "#{Location.to_string decl.location}:\tValidating interface: `#{name}`..."
|
316
|
-
builder.build_interface(decl.name.absolute!, decl).each_type do |type|
|
317
|
-
env.validate type, namespace: Namespace.root
|
318
|
-
end
|
392
|
+
env.class_decls.each_key do |name|
|
393
|
+
stdout.puts "Validating class/module definition: `#{name}`..."
|
394
|
+
builder.build_instance(name).each_type do |type|
|
395
|
+
validator.validate_type type, context: [Namespace.root]
|
396
|
+
end
|
397
|
+
builder.build_singleton(name).each_type do |type|
|
398
|
+
validator.validate_type type, context: [Namespace.root]
|
319
399
|
end
|
320
400
|
end
|
321
401
|
|
322
|
-
env.
|
323
|
-
stdout.puts "
|
324
|
-
|
402
|
+
env.interface_decls.each_key do |name|
|
403
|
+
stdout.puts "Validating interface: `#{name}`..."
|
404
|
+
builder.build_interface(name).each_type do |type|
|
405
|
+
validator.validate_type type, context: [Namespace.root]
|
406
|
+
end
|
325
407
|
end
|
326
408
|
|
327
|
-
env.
|
328
|
-
stdout.puts "
|
329
|
-
|
409
|
+
env.constant_decls.each do |name, const|
|
410
|
+
stdout.puts "Validating constant: `#{name}`..."
|
411
|
+
validator.validate_type const.decl.type, context: const.context
|
330
412
|
end
|
331
413
|
|
332
|
-
env.
|
333
|
-
stdout.puts "
|
334
|
-
|
414
|
+
env.global_decls.each do |name, global|
|
415
|
+
stdout.puts "Validating global: `#{name}`..."
|
416
|
+
validator.validate_type global.decl.type, context: [Namespace.root]
|
417
|
+
end
|
418
|
+
|
419
|
+
env.alias_decls.each do |name, decl|
|
420
|
+
stdout.puts "Validating alias: `#{name}`..."
|
421
|
+
validator.validate_type decl.decl.type, context: decl.context
|
335
422
|
end
|
336
423
|
end
|
337
424
|
|
@@ -339,7 +426,20 @@ module RBS
|
|
339
426
|
context = nil
|
340
427
|
|
341
428
|
OptionParser.new do |opts|
|
342
|
-
opts.
|
429
|
+
opts.banner = <<EOU
|
430
|
+
Usage: rbs constant [options...] [name]
|
431
|
+
|
432
|
+
Resolve constant based on RBS.
|
433
|
+
|
434
|
+
Examples:
|
435
|
+
|
436
|
+
$ rbs constant ::Object
|
437
|
+
$ rbs constant UTF_8
|
438
|
+
$ rbs constant --context=::Encoding UTF_8
|
439
|
+
|
440
|
+
Options:
|
441
|
+
EOU
|
442
|
+
opts.on("--context CONTEXT", "Name of the module where the constant resolution starts") {|c| context = c }
|
343
443
|
end.order!(args)
|
344
444
|
|
345
445
|
unless args.size == 1
|
@@ -351,8 +451,7 @@ module RBS
|
|
351
451
|
|
352
452
|
options.setup(loader)
|
353
453
|
|
354
|
-
env = Environment.
|
355
|
-
loader.load(env: env)
|
454
|
+
env = Environment.from_loader(loader).resolve_type_names
|
356
455
|
|
357
456
|
builder = DefinitionBuilder.new(env: env)
|
358
457
|
table = ConstantTable.new(builder: builder)
|
@@ -371,11 +470,20 @@ module RBS
|
|
371
470
|
end
|
372
471
|
end
|
373
472
|
|
374
|
-
def run_version(args, options)
|
375
|
-
stdout.puts "rbs #{VERSION}"
|
376
|
-
end
|
377
|
-
|
378
473
|
def run_paths(args, options)
|
474
|
+
OptionParser.new do |opts|
|
475
|
+
opts.banner = <<EOU
|
476
|
+
Usage: rbs paths
|
477
|
+
|
478
|
+
Show paths to directories where the RBS files are loaded from.
|
479
|
+
|
480
|
+
Examples:
|
481
|
+
|
482
|
+
$ rbs paths
|
483
|
+
$ tbs -r set paths
|
484
|
+
EOU
|
485
|
+
end.parse!(args)
|
486
|
+
|
379
487
|
loader = EnvironmentLoader.new()
|
380
488
|
|
381
489
|
options.setup(loader)
|
@@ -423,16 +531,30 @@ module RBS
|
|
423
531
|
owners_included = []
|
424
532
|
|
425
533
|
OptionParser.new do |opts|
|
426
|
-
opts.
|
534
|
+
opts.banner = <<EOU
|
535
|
+
Usage: rbs prototype runtime [options...] [pattern...]
|
536
|
+
|
537
|
+
Generate RBS prototype based on runtime introspection.
|
538
|
+
It loads Ruby code specified in [options] and generates RBS prototypes for classes matches to [pattern].
|
539
|
+
|
540
|
+
Examples:
|
541
|
+
|
542
|
+
$ rbs prototype runtime String
|
543
|
+
$ rbs prototype runtime --require set Set
|
544
|
+
$ rbs prototype runtime -R lib/rbs RBS::*
|
545
|
+
|
546
|
+
Options:
|
547
|
+
EOU
|
548
|
+
opts.on("-r", "--require LIB", "Load library using `require`") do |lib|
|
427
549
|
require_libs << lib
|
428
550
|
end
|
429
|
-
opts.on("--require-relative LIB") do |lib|
|
551
|
+
opts.on("-R", "--require-relative LIB", "Load library using `require_relative`") do |lib|
|
430
552
|
relative_libs << lib
|
431
553
|
end
|
432
|
-
opts.on("--merge") do
|
554
|
+
opts.on("--merge", "Merge generated prototype RBS with existing RBS") do
|
433
555
|
merge = true
|
434
556
|
end
|
435
|
-
opts.on("--method-owner CLASS") do |klass|
|
557
|
+
opts.on("--method-owner CLASS", "Generate method prototypes if the owner of the method is [CLASS]") do |klass|
|
436
558
|
owners_included << klass
|
437
559
|
end
|
438
560
|
end.parse!(args)
|
@@ -441,8 +563,7 @@ module RBS
|
|
441
563
|
|
442
564
|
options.setup(loader)
|
443
565
|
|
444
|
-
env = Environment.
|
445
|
-
loader.load(env: env)
|
566
|
+
env = Environment.from_loader(loader).resolve_type_names
|
446
567
|
|
447
568
|
require_libs.each do |lib|
|
448
569
|
require(lib)
|
@@ -454,15 +575,49 @@ module RBS
|
|
454
575
|
|
455
576
|
decls = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included).decls
|
456
577
|
else
|
457
|
-
stdout.puts
|
578
|
+
stdout.puts <<EOU
|
579
|
+
Usage: rbs prototype [generator...] [args...]
|
580
|
+
|
581
|
+
Generate prototype of RBS files.
|
582
|
+
Supported generators are rb, rbi, runtime.
|
583
|
+
|
584
|
+
Examples:
|
585
|
+
|
586
|
+
$ rbs prototype rb foo.rb
|
587
|
+
$ rbs prototype rbi foo.rbi
|
588
|
+
$ rbs prototype runtime String
|
589
|
+
EOU
|
458
590
|
exit 1
|
459
591
|
end
|
460
592
|
|
461
|
-
|
462
|
-
|
593
|
+
if decls
|
594
|
+
writer = Writer.new(out: stdout)
|
595
|
+
writer.write decls
|
596
|
+
else
|
597
|
+
exit 1
|
598
|
+
end
|
463
599
|
end
|
464
600
|
|
465
601
|
def run_prototype_file(format, args)
|
602
|
+
opts = OptionParser.new
|
603
|
+
opts.banner = <<EOU
|
604
|
+
Usage: rbs prototype #{format} [options...] [files...]
|
605
|
+
|
606
|
+
Generate RBS prototype from source code.
|
607
|
+
It parses specified Ruby code and and generates RBS prototypes.
|
608
|
+
|
609
|
+
Examples:
|
610
|
+
|
611
|
+
$ rbs prototype rb lib/foo.rb
|
612
|
+
$ rbs prototype rbi sorbet/rbi/foo.rbi
|
613
|
+
EOU
|
614
|
+
opts.parse!(args)
|
615
|
+
|
616
|
+
if args.empty?
|
617
|
+
stdout.puts opts
|
618
|
+
return nil
|
619
|
+
end
|
620
|
+
|
466
621
|
parser = case format
|
467
622
|
when "rbi"
|
468
623
|
Prototype::RBI.new()
|
@@ -483,9 +638,19 @@ module RBS
|
|
483
638
|
vendor_dir = Pathname("vendor/sigs")
|
484
639
|
|
485
640
|
OptionParser.new do |opts|
|
486
|
-
opts.banner =
|
487
|
-
|
488
|
-
|
641
|
+
opts.banner = <<-EOB
|
642
|
+
Usage: rbs vendor [options...] [gems...]
|
643
|
+
|
644
|
+
Vendor signatures in the project directory.
|
645
|
+
This command ignores the RBS loading global options, `-r` and `-I`.
|
646
|
+
|
647
|
+
Examples:
|
648
|
+
|
649
|
+
$ rbs vendor
|
650
|
+
$ rbs vendor --vendor-dir=sig
|
651
|
+
$ rbs vendor --no-stdlib
|
652
|
+
|
653
|
+
Options:
|
489
654
|
EOB
|
490
655
|
|
491
656
|
opts.on("--[no-]clean", "Clean vendor directory (default: no)") do |v|
|
@@ -528,6 +693,18 @@ module RBS
|
|
528
693
|
end
|
529
694
|
|
530
695
|
def run_parse(args, options)
|
696
|
+
OptionParser.new do |opts|
|
697
|
+
opts.banner = <<-EOB
|
698
|
+
Usage: rbs parse [files...]
|
699
|
+
|
700
|
+
Parse given RBS files and print syntax errors.
|
701
|
+
|
702
|
+
Examples:
|
703
|
+
|
704
|
+
$ rbs parse sig/app/models.rbs sig/app/controllers.rbs
|
705
|
+
EOB
|
706
|
+
end.parse!(args)
|
707
|
+
|
531
708
|
loader = EnvironmentLoader.new()
|
532
709
|
|
533
710
|
syntax_error = false
|
@@ -545,6 +722,7 @@ module RBS
|
|
545
722
|
syntax_error = true
|
546
723
|
end
|
547
724
|
end
|
725
|
+
|
548
726
|
exit 1 if syntax_error
|
549
727
|
end
|
550
728
|
|