rbs 0.4.0 → 0.9.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 +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
|
|