rbs 0.4.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +7 -1
- data/.gitignore +1 -1
- data/CHANGELOG.md +35 -0
- data/Gemfile +14 -0
- data/README.md +86 -47
- data/Rakefile +53 -21
- data/bin/rbs-prof +9 -0
- data/bin/run_in_md.rb +49 -0
- data/docs/stdlib.md +0 -2
- data/docs/syntax.md +6 -3
- data/goodcheck.yml +65 -0
- data/lib/rbs.rb +3 -0
- data/lib/rbs/ast/comment.rb +6 -0
- data/lib/rbs/ast/declarations.rb +106 -13
- data/lib/rbs/ast/members.rb +41 -17
- data/lib/rbs/cli.rb +317 -121
- data/lib/rbs/constant.rb +4 -4
- data/lib/rbs/constant_table.rb +51 -45
- data/lib/rbs/definition.rb +175 -59
- data/lib/rbs/definition_builder.rb +814 -604
- data/lib/rbs/environment.rb +352 -210
- data/lib/rbs/environment_walker.rb +14 -23
- data/lib/rbs/errors.rb +184 -3
- data/lib/rbs/factory.rb +14 -0
- data/lib/rbs/location.rb +15 -0
- data/lib/rbs/parser.y +100 -34
- data/lib/rbs/prototype/rb.rb +101 -113
- data/lib/rbs/prototype/rbi.rb +5 -3
- data/lib/rbs/prototype/runtime.rb +11 -7
- data/lib/rbs/substitution.rb +12 -1
- data/lib/rbs/test.rb +82 -3
- data/lib/rbs/test/errors.rb +5 -1
- data/lib/rbs/test/hook.rb +133 -259
- data/lib/rbs/test/observer.rb +17 -0
- data/lib/rbs/test/setup.rb +35 -19
- data/lib/rbs/test/setup_helper.rb +29 -0
- data/lib/rbs/test/spy.rb +0 -321
- data/lib/rbs/test/tester.rb +116 -0
- data/lib/rbs/test/type_check.rb +43 -7
- data/lib/rbs/type_name_resolver.rb +58 -0
- data/lib/rbs/types.rb +94 -2
- data/lib/rbs/validator.rb +55 -0
- data/lib/rbs/variance_calculator.rb +12 -2
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +127 -91
- data/rbs.gemspec +0 -10
- data/schema/decls.json +36 -10
- data/schema/members.json +3 -0
- data/stdlib/benchmark/benchmark.rbs +151 -151
- data/stdlib/builtin/enumerable.rbs +3 -3
- data/stdlib/builtin/file.rbs +0 -3
- data/stdlib/builtin/io.rbs +4 -4
- data/stdlib/builtin/proc.rbs +1 -2
- 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 +7 -1
- data/stdlib/logger/formatter.rbs +23 -0
- data/stdlib/logger/log_device.rbs +39 -0
- data/stdlib/logger/logger.rbs +507 -0
- data/stdlib/logger/period.rbs +7 -0
- data/stdlib/logger/severity.rbs +8 -0
- 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/pty/pty.rbs +159 -0
- data/stdlib/tmpdir/tmpdir.rbs +1 -1
- metadata +19 -130
- data/lib/rbs/test/test_helper.rb +0 -183
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,33 +55,44 @@ 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
|
|
66
66
|
opts
|
67
67
|
end
|
68
68
|
|
69
|
+
def has_parser?
|
70
|
+
defined?(RubyVM::AbstractSyntaxTree)
|
71
|
+
end
|
72
|
+
|
69
73
|
def run(args)
|
70
74
|
options = LibraryOptions.new
|
71
75
|
|
72
76
|
opts = OptionParser.new
|
73
77
|
opts.banner = <<~USAGE
|
74
|
-
Usage: rbs [options]
|
75
|
-
|
78
|
+
Usage: rbs [options...] [command...]
|
79
|
+
|
80
|
+
Available commands: #{COMMANDS.join(", ")}, version, help.
|
81
|
+
|
82
|
+
Options:
|
76
83
|
USAGE
|
77
84
|
library_parse(opts, options: options)
|
78
85
|
parse_logging_options(opts)
|
86
|
+
opts.version = RBS::VERSION
|
79
87
|
|
80
88
|
opts.order!(args)
|
81
89
|
|
82
90
|
command = args.shift&.to_sym
|
83
91
|
|
84
|
-
|
92
|
+
case command
|
93
|
+
when :version
|
94
|
+
stdout.puts opts.ver
|
95
|
+
when *COMMANDS
|
85
96
|
__send__ :"run_#{command}", args, options
|
86
97
|
else
|
87
98
|
stdout.puts opts.help
|
@@ -89,101 +100,151 @@ module RBS
|
|
89
100
|
end
|
90
101
|
|
91
102
|
def run_ast(args, options)
|
92
|
-
|
103
|
+
OptionParser.new do |opts|
|
104
|
+
opts.banner = <<EOB
|
105
|
+
Usage: rbs ast [patterns...]
|
106
|
+
|
107
|
+
Print JSON AST of loaded environment.
|
108
|
+
You can specify patterns to filter declarations with the file names.
|
109
|
+
|
110
|
+
Examples:
|
93
111
|
|
112
|
+
$ rbs ast
|
113
|
+
$ rbs ast 'basic_object.rbs'
|
114
|
+
$ rbs -I ./sig ast ./sig
|
115
|
+
$ rbs -I ./sig ast '*/models/*.rbs'
|
116
|
+
EOB
|
117
|
+
end.order!(args)
|
118
|
+
|
119
|
+
patterns = args.map do |arg|
|
120
|
+
path = Pathname(arg)
|
121
|
+
if path.exist?
|
122
|
+
# Pathname means a directory or a file
|
123
|
+
path
|
124
|
+
else
|
125
|
+
# String means a `fnmatch` pattern
|
126
|
+
arg
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
loader = EnvironmentLoader.new()
|
94
131
|
options.setup(loader)
|
95
132
|
|
96
|
-
env = Environment.
|
97
|
-
loader.load(env: env)
|
133
|
+
env = Environment.from_loader(loader).resolve_type_names
|
98
134
|
|
99
|
-
|
135
|
+
decls = env.declarations.select do |decl|
|
136
|
+
name = decl.location.buffer.name
|
137
|
+
|
138
|
+
patterns.empty? || patterns.any? do |pat|
|
139
|
+
case pat
|
140
|
+
when Pathname
|
141
|
+
Pathname(name).ascend.any? {|p| p == pat }
|
142
|
+
when String
|
143
|
+
name.end_with?(pat) || File.fnmatch(pat, name, File::FNM_EXTGLOB)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
stdout.print JSON.generate(decls)
|
100
149
|
stdout.flush
|
101
150
|
end
|
102
151
|
|
103
152
|
def run_list(args, options)
|
104
|
-
list = []
|
153
|
+
list = Set[]
|
105
154
|
|
106
155
|
OptionParser.new do |opts|
|
107
|
-
opts.
|
108
|
-
|
109
|
-
|
156
|
+
opts.banner = <<EOB
|
157
|
+
Usage: rbs list [options...]
|
158
|
+
|
159
|
+
List classes, modules, and interfaces.
|
160
|
+
|
161
|
+
Examples:
|
162
|
+
|
163
|
+
$ rbs list
|
164
|
+
$ rbs list --class --module --interface
|
165
|
+
|
166
|
+
Options:
|
167
|
+
EOB
|
168
|
+
opts.on("--class", "List classes") { list << :class }
|
169
|
+
opts.on("--module", "List modules") { list << :module }
|
170
|
+
opts.on("--interface", "List interfaces") { list << :interface }
|
110
171
|
end.order!(args)
|
111
172
|
|
112
|
-
list.
|
173
|
+
list.merge([:class, :module, :interface]) if list.empty?
|
113
174
|
|
114
175
|
loader = EnvironmentLoader.new()
|
115
|
-
|
116
176
|
options.setup(loader)
|
117
177
|
|
118
|
-
env = Environment.
|
119
|
-
loader.load(env: env)
|
178
|
+
env = Environment.from_loader(loader).resolve_type_names
|
120
179
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
if list.include?(:interface)
|
133
|
-
stdout.puts "#{type_name} (interface)"
|
180
|
+
if list.include?(:class) || list.include?(:module)
|
181
|
+
env.class_decls.each do |name, entry|
|
182
|
+
case entry
|
183
|
+
when Environment::ModuleEntry
|
184
|
+
if list.include?(:module)
|
185
|
+
stdout.puts "#{name} (module)"
|
186
|
+
end
|
187
|
+
when Environment::ClassEntry
|
188
|
+
if list.include?(:class)
|
189
|
+
stdout.puts "#{name} (class)"
|
190
|
+
end
|
134
191
|
end
|
135
192
|
end
|
136
193
|
end
|
194
|
+
|
195
|
+
if list.include?(:interface)
|
196
|
+
env.interface_decls.each do |name, entry|
|
197
|
+
stdout.puts "#{name} (interface)"
|
198
|
+
end
|
199
|
+
end
|
137
200
|
end
|
138
201
|
|
139
202
|
def run_ancestors(args, options)
|
140
203
|
kind = :instance
|
141
204
|
|
142
205
|
OptionParser.new do |opts|
|
143
|
-
opts.
|
144
|
-
|
206
|
+
opts.banner = <<EOU
|
207
|
+
Usage: rbs ancestors [options...] [type_name]
|
208
|
+
|
209
|
+
Show ancestors of the given class or module.
|
210
|
+
|
211
|
+
Examples:
|
212
|
+
|
213
|
+
$ rbs ancestors --instance String
|
214
|
+
$ rbs ancestors --singleton Array
|
215
|
+
|
216
|
+
Options:
|
217
|
+
EOU
|
218
|
+
opts.on("--instance", "Ancestors of instance of the given type_name (default)") { kind = :instance }
|
219
|
+
opts.on("--singleton", "Ancestors of singleton of the given type_name") { kind = :singleton }
|
145
220
|
end.order!(args)
|
146
221
|
|
147
222
|
loader = EnvironmentLoader.new()
|
148
|
-
|
149
223
|
options.setup(loader)
|
150
224
|
|
151
|
-
env = Environment.
|
152
|
-
loader.load(env: env)
|
225
|
+
env = Environment.from_loader(loader).resolve_type_names
|
153
226
|
|
154
227
|
builder = DefinitionBuilder.new(env: env)
|
155
228
|
type_name = parse_type_name(args[0]).absolute!
|
156
229
|
|
157
|
-
if env.
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
Definition::Ancestor::Singleton.new(name: type_name)
|
165
|
-
end
|
230
|
+
if env.class_decls.key?(type_name)
|
231
|
+
ancestors = case kind
|
232
|
+
when :instance
|
233
|
+
builder.instance_ancestors(type_name)
|
234
|
+
when :singleton
|
235
|
+
builder.singleton_ancestors(type_name)
|
236
|
+
end
|
166
237
|
|
167
|
-
ancestors
|
168
|
-
|
169
|
-
ancestors.each do |ancestor|
|
238
|
+
ancestors.ancestors.each do |ancestor|
|
170
239
|
case ancestor
|
171
240
|
when Definition::Ancestor::Singleton
|
172
241
|
stdout.puts "singleton(#{ancestor.name})"
|
173
|
-
when Definition::Ancestor::ExtensionSingleton
|
174
|
-
stdout.puts "singleton(#{ancestor.name} (#{ancestor.extension_name}))"
|
175
242
|
when Definition::Ancestor::Instance
|
176
243
|
if ancestor.args.empty?
|
177
244
|
stdout.puts ancestor.name.to_s
|
178
245
|
else
|
179
246
|
stdout.puts "#{ancestor.name}[#{ancestor.args.join(", ")}]"
|
180
247
|
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
248
|
end
|
188
249
|
end
|
189
250
|
else
|
@@ -196,10 +257,21 @@ module RBS
|
|
196
257
|
inherit = true
|
197
258
|
|
198
259
|
OptionParser.new do |opts|
|
199
|
-
opts.
|
200
|
-
|
201
|
-
|
202
|
-
|
260
|
+
opts.banner = <<EOU
|
261
|
+
Usage: rbs methods [options...] [type_name]
|
262
|
+
|
263
|
+
Show methods defined in the class or module.
|
264
|
+
|
265
|
+
Examples:
|
266
|
+
|
267
|
+
$ rbs methods --instance Kernel
|
268
|
+
$ rbs methods --singleton --no-inherit String
|
269
|
+
|
270
|
+
Options:
|
271
|
+
EOU
|
272
|
+
opts.on("--instance", "Show instance methods (default)") { kind = :instance }
|
273
|
+
opts.on("--singleton", "Show singleton methods") { kind = :singleton }
|
274
|
+
opts.on("--[no-]inherit", "Show methods defined in super class and mixed modules too") {|v| inherit = v }
|
203
275
|
end.order!(args)
|
204
276
|
|
205
277
|
unless args.size == 1
|
@@ -208,16 +280,14 @@ module RBS
|
|
208
280
|
end
|
209
281
|
|
210
282
|
loader = EnvironmentLoader.new()
|
211
|
-
|
212
283
|
options.setup(loader)
|
213
284
|
|
214
|
-
env = Environment.
|
215
|
-
loader.load(env: env)
|
285
|
+
env = Environment.from_loader(loader).resolve_type_names
|
216
286
|
|
217
287
|
builder = DefinitionBuilder.new(env: env)
|
218
288
|
type_name = parse_type_name(args[0]).absolute!
|
219
289
|
|
220
|
-
if env.
|
290
|
+
if env.class_decls.key?(type_name)
|
221
291
|
definition = case kind
|
222
292
|
when :instance
|
223
293
|
builder.build_instance(type_name)
|
@@ -227,7 +297,7 @@ module RBS
|
|
227
297
|
|
228
298
|
definition.methods.keys.sort.each do |name|
|
229
299
|
method = definition.methods[name]
|
230
|
-
if inherit || method.implemented_in ==
|
300
|
+
if inherit || method.implemented_in == type_name
|
231
301
|
stdout.puts "#{name} (#{method.accessibility})"
|
232
302
|
end
|
233
303
|
end
|
@@ -240,8 +310,20 @@ module RBS
|
|
240
310
|
kind = :instance
|
241
311
|
|
242
312
|
OptionParser.new do |opts|
|
243
|
-
opts.
|
244
|
-
|
313
|
+
opts.banner = <<EOU
|
314
|
+
Usage: rbs method [options...] [type_name] [method_name]
|
315
|
+
|
316
|
+
Show the information of the method specified by type_name and method_name.
|
317
|
+
|
318
|
+
Examples:
|
319
|
+
|
320
|
+
$ rbs method --instance Kernel puts
|
321
|
+
$ rbs method --singleton String try_convert
|
322
|
+
|
323
|
+
Options:
|
324
|
+
EOU
|
325
|
+
opts.on("--instance", "Show an instance method (default)") { kind = :instance }
|
326
|
+
opts.on("--singleton", "Show a singleton method") { kind = :singleton }
|
245
327
|
end.order!(args)
|
246
328
|
|
247
329
|
unless args.size == 2
|
@@ -250,17 +332,15 @@ module RBS
|
|
250
332
|
end
|
251
333
|
|
252
334
|
loader = EnvironmentLoader.new()
|
253
|
-
|
254
335
|
options.setup(loader)
|
255
336
|
|
256
|
-
env = Environment.
|
257
|
-
loader.load(env: env)
|
337
|
+
env = Environment.from_loader(loader).resolve_type_names
|
258
338
|
|
259
339
|
builder = DefinitionBuilder.new(env: env)
|
260
340
|
type_name = parse_type_name(args[0]).absolute!
|
261
341
|
method_name = args[1].to_sym
|
262
342
|
|
263
|
-
unless env.
|
343
|
+
unless env.class_decls.key?(type_name)
|
264
344
|
stdout.puts "Cannot find class: #{type_name}"
|
265
345
|
return
|
266
346
|
end
|
@@ -280,8 +360,8 @@ module RBS
|
|
280
360
|
end
|
281
361
|
|
282
362
|
stdout.puts "#{type_name}#{kind == :instance ? "#" : "."}#{method_name}"
|
283
|
-
stdout.puts " defined_in: #{method.defined_in
|
284
|
-
stdout.puts " implementation: #{method.implemented_in
|
363
|
+
stdout.puts " defined_in: #{method.defined_in}"
|
364
|
+
stdout.puts " implementation: #{method.implemented_in}"
|
285
365
|
stdout.puts " accessibility: #{method.accessibility}"
|
286
366
|
stdout.puts " types:"
|
287
367
|
separator = " "
|
@@ -292,46 +372,60 @@ module RBS
|
|
292
372
|
end
|
293
373
|
|
294
374
|
def run_validate(args, options)
|
375
|
+
OptionParser.new do |opts|
|
376
|
+
opts.banner = <<EOU
|
377
|
+
Usage: rbs validate
|
378
|
+
|
379
|
+
Validate RBS files. It ensures the type names in RBS files are present and the type applications have correct arity.
|
380
|
+
|
381
|
+
Examples:
|
382
|
+
|
383
|
+
$ rbs validate
|
384
|
+
EOU
|
385
|
+
end.parse!(args)
|
386
|
+
|
295
387
|
loader = EnvironmentLoader.new()
|
296
388
|
|
297
389
|
options.setup(loader)
|
298
390
|
|
299
|
-
env = Environment.
|
300
|
-
loader.load(env: env)
|
391
|
+
env = Environment.from_loader(loader).resolve_type_names
|
301
392
|
|
302
393
|
builder = DefinitionBuilder.new(env: env)
|
394
|
+
validator = Validator.new(env: env, resolver: TypeNameResolver.from_env(env))
|
303
395
|
|
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
|
396
|
+
env.class_decls.each_key do |name|
|
397
|
+
stdout.puts "Validating class/module definition: `#{name}`..."
|
398
|
+
builder.build_instance(name).each_type do |type|
|
399
|
+
validator.validate_type type, context: [Namespace.root]
|
400
|
+
end
|
401
|
+
builder.build_singleton(name).each_type do |type|
|
402
|
+
validator.validate_type type, context: [Namespace.root]
|
319
403
|
end
|
320
404
|
end
|
321
405
|
|
322
|
-
env.
|
323
|
-
stdout.puts "
|
324
|
-
|
406
|
+
env.interface_decls.each_key do |name|
|
407
|
+
stdout.puts "Validating interface: `#{name}`..."
|
408
|
+
builder.build_interface(name).each_type do |type|
|
409
|
+
validator.validate_type type, context: [Namespace.root]
|
410
|
+
end
|
325
411
|
end
|
326
412
|
|
327
|
-
env.
|
328
|
-
stdout.puts "
|
329
|
-
|
413
|
+
env.constant_decls.each do |name, const|
|
414
|
+
stdout.puts "Validating constant: `#{name}`..."
|
415
|
+
validator.validate_type const.decl.type, context: const.context
|
416
|
+
builder.ensure_namespace!(name.namespace, location: const.decl.location)
|
330
417
|
end
|
331
418
|
|
332
|
-
env.
|
333
|
-
stdout.puts "
|
334
|
-
|
419
|
+
env.global_decls.each do |name, global|
|
420
|
+
stdout.puts "Validating global: `#{name}`..."
|
421
|
+
validator.validate_type global.decl.type, context: [Namespace.root]
|
422
|
+
end
|
423
|
+
|
424
|
+
env.alias_decls.each do |name, decl|
|
425
|
+
stdout.puts "Validating alias: `#{name}`..."
|
426
|
+
builder.expand_alias(name).tap do |type|
|
427
|
+
validator.validate_type type, context: [Namespace.root]
|
428
|
+
end
|
335
429
|
end
|
336
430
|
end
|
337
431
|
|
@@ -339,7 +433,20 @@ module RBS
|
|
339
433
|
context = nil
|
340
434
|
|
341
435
|
OptionParser.new do |opts|
|
342
|
-
opts.
|
436
|
+
opts.banner = <<EOU
|
437
|
+
Usage: rbs constant [options...] [name]
|
438
|
+
|
439
|
+
Resolve constant based on RBS.
|
440
|
+
|
441
|
+
Examples:
|
442
|
+
|
443
|
+
$ rbs constant ::Object
|
444
|
+
$ rbs constant UTF_8
|
445
|
+
$ rbs constant --context=::Encoding UTF_8
|
446
|
+
|
447
|
+
Options:
|
448
|
+
EOU
|
449
|
+
opts.on("--context CONTEXT", "Name of the module where the constant resolution starts") {|c| context = c }
|
343
450
|
end.order!(args)
|
344
451
|
|
345
452
|
unless args.size == 1
|
@@ -351,8 +458,7 @@ module RBS
|
|
351
458
|
|
352
459
|
options.setup(loader)
|
353
460
|
|
354
|
-
env = Environment.
|
355
|
-
loader.load(env: env)
|
461
|
+
env = Environment.from_loader(loader).resolve_type_names
|
356
462
|
|
357
463
|
builder = DefinitionBuilder.new(env: env)
|
358
464
|
table = ConstantTable.new(builder: builder)
|
@@ -371,11 +477,20 @@ module RBS
|
|
371
477
|
end
|
372
478
|
end
|
373
479
|
|
374
|
-
def run_version(args, options)
|
375
|
-
stdout.puts "rbs #{VERSION}"
|
376
|
-
end
|
377
|
-
|
378
480
|
def run_paths(args, options)
|
481
|
+
OptionParser.new do |opts|
|
482
|
+
opts.banner = <<EOU
|
483
|
+
Usage: rbs paths
|
484
|
+
|
485
|
+
Show paths to directories where the RBS files are loaded from.
|
486
|
+
|
487
|
+
Examples:
|
488
|
+
|
489
|
+
$ rbs paths
|
490
|
+
$ tbs -r set paths
|
491
|
+
EOU
|
492
|
+
end.parse!(args)
|
493
|
+
|
379
494
|
loader = EnvironmentLoader.new()
|
380
495
|
|
381
496
|
options.setup(loader)
|
@@ -423,16 +538,30 @@ module RBS
|
|
423
538
|
owners_included = []
|
424
539
|
|
425
540
|
OptionParser.new do |opts|
|
426
|
-
opts.
|
541
|
+
opts.banner = <<EOU
|
542
|
+
Usage: rbs prototype runtime [options...] [pattern...]
|
543
|
+
|
544
|
+
Generate RBS prototype based on runtime introspection.
|
545
|
+
It loads Ruby code specified in [options] and generates RBS prototypes for classes matches to [pattern].
|
546
|
+
|
547
|
+
Examples:
|
548
|
+
|
549
|
+
$ rbs prototype runtime String
|
550
|
+
$ rbs prototype runtime --require set Set
|
551
|
+
$ rbs prototype runtime -R lib/rbs RBS::*
|
552
|
+
|
553
|
+
Options:
|
554
|
+
EOU
|
555
|
+
opts.on("-r", "--require LIB", "Load library using `require`") do |lib|
|
427
556
|
require_libs << lib
|
428
557
|
end
|
429
|
-
opts.on("--require-relative LIB") do |lib|
|
558
|
+
opts.on("-R", "--require-relative LIB", "Load library using `require_relative`") do |lib|
|
430
559
|
relative_libs << lib
|
431
560
|
end
|
432
|
-
opts.on("--merge") do
|
561
|
+
opts.on("--merge", "Merge generated prototype RBS with existing RBS") do
|
433
562
|
merge = true
|
434
563
|
end
|
435
|
-
opts.on("--method-owner CLASS") do |klass|
|
564
|
+
opts.on("--method-owner CLASS", "Generate method prototypes if the owner of the method is [CLASS]") do |klass|
|
436
565
|
owners_included << klass
|
437
566
|
end
|
438
567
|
end.parse!(args)
|
@@ -441,8 +570,7 @@ module RBS
|
|
441
570
|
|
442
571
|
options.setup(loader)
|
443
572
|
|
444
|
-
env = Environment.
|
445
|
-
loader.load(env: env)
|
573
|
+
env = Environment.from_loader(loader).resolve_type_names
|
446
574
|
|
447
575
|
require_libs.each do |lib|
|
448
576
|
require(lib)
|
@@ -454,15 +582,60 @@ module RBS
|
|
454
582
|
|
455
583
|
decls = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included).decls
|
456
584
|
else
|
457
|
-
stdout.puts
|
585
|
+
stdout.puts <<EOU
|
586
|
+
Usage: rbs prototype [generator...] [args...]
|
587
|
+
|
588
|
+
Generate prototype of RBS files.
|
589
|
+
Supported generators are rb, rbi, runtime.
|
590
|
+
|
591
|
+
Examples:
|
592
|
+
|
593
|
+
$ rbs prototype rb foo.rb
|
594
|
+
$ rbs prototype rbi foo.rbi
|
595
|
+
$ rbs prototype runtime String
|
596
|
+
EOU
|
458
597
|
exit 1
|
459
598
|
end
|
460
599
|
|
461
|
-
|
462
|
-
|
600
|
+
if decls
|
601
|
+
writer = Writer.new(out: stdout)
|
602
|
+
writer.write decls
|
603
|
+
else
|
604
|
+
exit 1
|
605
|
+
end
|
463
606
|
end
|
464
607
|
|
465
608
|
def run_prototype_file(format, args)
|
609
|
+
availability = unless has_parser?
|
610
|
+
"\n** This command does not work on this interpreter (#{RUBY_ENGINE}) **\n"
|
611
|
+
end
|
612
|
+
|
613
|
+
opts = OptionParser.new
|
614
|
+
opts.banner = <<EOU
|
615
|
+
Usage: rbs prototype #{format} [options...] [files...]
|
616
|
+
#{availability}
|
617
|
+
Generate RBS prototype from source code.
|
618
|
+
It parses specified Ruby code and and generates RBS prototypes.
|
619
|
+
|
620
|
+
It only works on MRI because it parses Ruby code with `RubyVM::AbstractSyntaxTree`.
|
621
|
+
|
622
|
+
Examples:
|
623
|
+
|
624
|
+
$ rbs prototype rb lib/foo.rb
|
625
|
+
$ rbs prototype rbi sorbet/rbi/foo.rbi
|
626
|
+
EOU
|
627
|
+
opts.parse!(args)
|
628
|
+
|
629
|
+
unless has_parser?
|
630
|
+
stdout.puts "Not supported on this interpreter (#{RUBY_ENGINE})."
|
631
|
+
exit 1
|
632
|
+
end
|
633
|
+
|
634
|
+
if args.empty?
|
635
|
+
stdout.puts opts
|
636
|
+
return nil
|
637
|
+
end
|
638
|
+
|
466
639
|
parser = case format
|
467
640
|
when "rbi"
|
468
641
|
Prototype::RBI.new()
|
@@ -483,9 +656,19 @@ module RBS
|
|
483
656
|
vendor_dir = Pathname("vendor/sigs")
|
484
657
|
|
485
658
|
OptionParser.new do |opts|
|
486
|
-
opts.banner =
|
487
|
-
|
488
|
-
|
659
|
+
opts.banner = <<-EOB
|
660
|
+
Usage: rbs vendor [options...] [gems...]
|
661
|
+
|
662
|
+
Vendor signatures in the project directory.
|
663
|
+
This command ignores the RBS loading global options, `-r` and `-I`.
|
664
|
+
|
665
|
+
Examples:
|
666
|
+
|
667
|
+
$ rbs vendor
|
668
|
+
$ rbs vendor --vendor-dir=sig
|
669
|
+
$ rbs vendor --no-stdlib
|
670
|
+
|
671
|
+
Options:
|
489
672
|
EOB
|
490
673
|
|
491
674
|
opts.on("--[no-]clean", "Clean vendor directory (default: no)") do |v|
|
@@ -528,6 +711,18 @@ module RBS
|
|
528
711
|
end
|
529
712
|
|
530
713
|
def run_parse(args, options)
|
714
|
+
OptionParser.new do |opts|
|
715
|
+
opts.banner = <<-EOB
|
716
|
+
Usage: rbs parse [files...]
|
717
|
+
|
718
|
+
Parse given RBS files and print syntax errors.
|
719
|
+
|
720
|
+
Examples:
|
721
|
+
|
722
|
+
$ rbs parse sig/app/models.rbs sig/app/controllers.rbs
|
723
|
+
EOB
|
724
|
+
end.parse!(args)
|
725
|
+
|
531
726
|
loader = EnvironmentLoader.new()
|
532
727
|
|
533
728
|
syntax_error = false
|
@@ -545,6 +740,7 @@ module RBS
|
|
545
740
|
syntax_error = true
|
546
741
|
end
|
547
742
|
end
|
743
|
+
|
548
744
|
exit 1 if syntax_error
|
549
745
|
end
|
550
746
|
|