rbs 0.2.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.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +28 -0
  3. data/.gitignore +12 -0
  4. data/.rubocop.yml +15 -0
  5. data/BSDL +22 -0
  6. data/CHANGELOG.md +9 -0
  7. data/COPYING +56 -0
  8. data/Gemfile +6 -0
  9. data/README.md +93 -0
  10. data/Rakefile +142 -0
  11. data/bin/annotate-with-rdoc +157 -0
  12. data/bin/console +14 -0
  13. data/bin/query-rdoc +103 -0
  14. data/bin/setup +10 -0
  15. data/bin/sort +89 -0
  16. data/bin/test_runner.rb +16 -0
  17. data/docs/CONTRIBUTING.md +97 -0
  18. data/docs/sigs.md +148 -0
  19. data/docs/stdlib.md +152 -0
  20. data/docs/syntax.md +528 -0
  21. data/exe/rbs +7 -0
  22. data/lib/rbs.rb +64 -0
  23. data/lib/rbs/ast/annotation.rb +27 -0
  24. data/lib/rbs/ast/comment.rb +27 -0
  25. data/lib/rbs/ast/declarations.rb +395 -0
  26. data/lib/rbs/ast/members.rb +362 -0
  27. data/lib/rbs/buffer.rb +50 -0
  28. data/lib/rbs/builtin_names.rb +55 -0
  29. data/lib/rbs/cli.rb +558 -0
  30. data/lib/rbs/constant.rb +26 -0
  31. data/lib/rbs/constant_table.rb +150 -0
  32. data/lib/rbs/definition.rb +170 -0
  33. data/lib/rbs/definition_builder.rb +919 -0
  34. data/lib/rbs/environment.rb +281 -0
  35. data/lib/rbs/environment_loader.rb +136 -0
  36. data/lib/rbs/environment_walker.rb +124 -0
  37. data/lib/rbs/errors.rb +187 -0
  38. data/lib/rbs/location.rb +102 -0
  39. data/lib/rbs/method_type.rb +123 -0
  40. data/lib/rbs/namespace.rb +91 -0
  41. data/lib/rbs/parser.y +1344 -0
  42. data/lib/rbs/prototype/rb.rb +553 -0
  43. data/lib/rbs/prototype/rbi.rb +587 -0
  44. data/lib/rbs/prototype/runtime.rb +381 -0
  45. data/lib/rbs/substitution.rb +46 -0
  46. data/lib/rbs/test.rb +26 -0
  47. data/lib/rbs/test/errors.rb +61 -0
  48. data/lib/rbs/test/hook.rb +294 -0
  49. data/lib/rbs/test/setup.rb +58 -0
  50. data/lib/rbs/test/spy.rb +325 -0
  51. data/lib/rbs/test/test_helper.rb +183 -0
  52. data/lib/rbs/test/type_check.rb +254 -0
  53. data/lib/rbs/type_name.rb +70 -0
  54. data/lib/rbs/types.rb +936 -0
  55. data/lib/rbs/variance_calculator.rb +138 -0
  56. data/lib/rbs/vendorer.rb +47 -0
  57. data/lib/rbs/version.rb +3 -0
  58. data/lib/rbs/writer.rb +269 -0
  59. data/lib/ruby/signature.rb +7 -0
  60. data/rbs.gemspec +46 -0
  61. data/stdlib/abbrev/abbrev.rbs +60 -0
  62. data/stdlib/base64/base64.rbs +71 -0
  63. data/stdlib/benchmark/benchmark.rbs +372 -0
  64. data/stdlib/builtin/array.rbs +1997 -0
  65. data/stdlib/builtin/basic_object.rbs +280 -0
  66. data/stdlib/builtin/binding.rbs +177 -0
  67. data/stdlib/builtin/builtin.rbs +45 -0
  68. data/stdlib/builtin/class.rbs +145 -0
  69. data/stdlib/builtin/comparable.rbs +116 -0
  70. data/stdlib/builtin/complex.rbs +400 -0
  71. data/stdlib/builtin/constants.rbs +37 -0
  72. data/stdlib/builtin/data.rbs +5 -0
  73. data/stdlib/builtin/deprecated.rbs +2 -0
  74. data/stdlib/builtin/dir.rbs +413 -0
  75. data/stdlib/builtin/encoding.rbs +607 -0
  76. data/stdlib/builtin/enumerable.rbs +404 -0
  77. data/stdlib/builtin/enumerator.rbs +260 -0
  78. data/stdlib/builtin/errno.rbs +781 -0
  79. data/stdlib/builtin/errors.rbs +582 -0
  80. data/stdlib/builtin/exception.rbs +194 -0
  81. data/stdlib/builtin/false_class.rbs +40 -0
  82. data/stdlib/builtin/fiber.rbs +68 -0
  83. data/stdlib/builtin/fiber_error.rbs +12 -0
  84. data/stdlib/builtin/file.rbs +1076 -0
  85. data/stdlib/builtin/file_test.rbs +59 -0
  86. data/stdlib/builtin/float.rbs +696 -0
  87. data/stdlib/builtin/gc.rbs +243 -0
  88. data/stdlib/builtin/hash.rbs +1029 -0
  89. data/stdlib/builtin/integer.rbs +707 -0
  90. data/stdlib/builtin/io.rbs +683 -0
  91. data/stdlib/builtin/kernel.rbs +576 -0
  92. data/stdlib/builtin/marshal.rbs +161 -0
  93. data/stdlib/builtin/match_data.rbs +271 -0
  94. data/stdlib/builtin/math.rbs +369 -0
  95. data/stdlib/builtin/method.rbs +185 -0
  96. data/stdlib/builtin/module.rbs +1104 -0
  97. data/stdlib/builtin/nil_class.rbs +82 -0
  98. data/stdlib/builtin/numeric.rbs +409 -0
  99. data/stdlib/builtin/object.rbs +824 -0
  100. data/stdlib/builtin/proc.rbs +429 -0
  101. data/stdlib/builtin/process.rbs +1227 -0
  102. data/stdlib/builtin/random.rbs +267 -0
  103. data/stdlib/builtin/range.rbs +226 -0
  104. data/stdlib/builtin/rational.rbs +424 -0
  105. data/stdlib/builtin/rb_config.rbs +57 -0
  106. data/stdlib/builtin/regexp.rbs +1083 -0
  107. data/stdlib/builtin/ruby_vm.rbs +14 -0
  108. data/stdlib/builtin/signal.rbs +55 -0
  109. data/stdlib/builtin/string.rbs +1901 -0
  110. data/stdlib/builtin/string_io.rbs +284 -0
  111. data/stdlib/builtin/struct.rbs +40 -0
  112. data/stdlib/builtin/symbol.rbs +228 -0
  113. data/stdlib/builtin/thread.rbs +1108 -0
  114. data/stdlib/builtin/thread_group.rbs +23 -0
  115. data/stdlib/builtin/time.rbs +1047 -0
  116. data/stdlib/builtin/trace_point.rbs +290 -0
  117. data/stdlib/builtin/true_class.rbs +46 -0
  118. data/stdlib/builtin/unbound_method.rbs +153 -0
  119. data/stdlib/builtin/warning.rbs +17 -0
  120. data/stdlib/coverage/coverage.rbs +62 -0
  121. data/stdlib/csv/csv.rbs +773 -0
  122. data/stdlib/erb/erb.rbs +392 -0
  123. data/stdlib/find/find.rbs +40 -0
  124. data/stdlib/ipaddr/ipaddr.rbs +247 -0
  125. data/stdlib/json/json.rbs +335 -0
  126. data/stdlib/pathname/pathname.rbs +1093 -0
  127. data/stdlib/prime/integer-extension.rbs +23 -0
  128. data/stdlib/prime/prime.rbs +188 -0
  129. data/stdlib/securerandom/securerandom.rbs +9 -0
  130. data/stdlib/set/set.rbs +301 -0
  131. data/stdlib/tmpdir/tmpdir.rbs +53 -0
  132. metadata +292 -0
@@ -0,0 +1,558 @@
1
+ require "optparse"
2
+
3
+ module RBS
4
+ class CLI
5
+ class LibraryOptions
6
+ attr_reader :libs
7
+ attr_reader :dirs
8
+ attr_accessor :no_stdlib
9
+
10
+ def initialize()
11
+ @libs = []
12
+ @dirs = []
13
+ @no_stdlib = false
14
+ end
15
+
16
+ def setup(loader)
17
+ libs.each do |lib|
18
+ loader.add(library: lib)
19
+ end
20
+
21
+ dirs.each do |dir|
22
+ loader.add(path: Pathname(dir))
23
+ end
24
+
25
+ loader.no_builtin! if no_stdlib
26
+
27
+ loader
28
+ end
29
+ end
30
+
31
+ attr_reader :stdout
32
+ attr_reader :stderr
33
+
34
+ def initialize(stdout:, stderr:)
35
+ @stdout = stdout
36
+ @stderr = stderr
37
+ end
38
+
39
+ COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :version, :parse]
40
+
41
+ def library_parse(opts, options:)
42
+ opts.on("-r LIBRARY") do |lib|
43
+ options.libs << lib
44
+ end
45
+
46
+ opts.on("-I DIR") do |dir|
47
+ options.dirs << dir
48
+ end
49
+
50
+ opts.on("--no-stdlib") do
51
+ options.no_stdlib = true
52
+ end
53
+
54
+ opts
55
+ end
56
+
57
+ def parse_logging_options(opts)
58
+ opts.on("--log-level=LEVEL", "Specify log level (defaults to `warn`)") do |level|
59
+ RBS.logger_level = level
60
+ end
61
+
62
+ opts.on("--log-output=OUTPUT", "Specify the file to output log (defaults to stderr)") do |output|
63
+ RBS.logger_output = File.open(output, "a")
64
+ end
65
+
66
+ opts
67
+ end
68
+
69
+ def run(args)
70
+ options = LibraryOptions.new
71
+
72
+ opts = OptionParser.new
73
+ opts.banner = <<~USAGE
74
+ Usage: rbs [options] COMMAND
75
+ Available commands: #{COMMANDS.join(", ")}
76
+ USAGE
77
+ library_parse(opts, options: options)
78
+ parse_logging_options(opts)
79
+
80
+ opts.order!(args)
81
+
82
+ command = args.shift&.to_sym
83
+
84
+ if COMMANDS.include?(command)
85
+ __send__ :"run_#{command}", args, options
86
+ else
87
+ stdout.puts opts.help
88
+ end
89
+ end
90
+
91
+ def run_ast(args, options)
92
+ loader = EnvironmentLoader.new()
93
+
94
+ options.setup(loader)
95
+
96
+ env = Environment.new()
97
+ loader.load(env: env)
98
+
99
+ stdout.print JSON.generate(env.declarations)
100
+ stdout.flush
101
+ end
102
+
103
+ def run_list(args, options)
104
+ list = []
105
+
106
+ OptionParser.new do |opts|
107
+ opts.on("--class") { list << :class }
108
+ opts.on("--module") { list << :module }
109
+ opts.on("--interface") { list << :interface }
110
+ end.order!(args)
111
+
112
+ list.push(:class, :module, :interface) if list.empty?
113
+
114
+ loader = EnvironmentLoader.new()
115
+
116
+ options.setup(loader)
117
+
118
+ env = Environment.new()
119
+ loader.load(env: env)
120
+
121
+ env.each_decl.sort_by {|name,| name.to_s }.each do |type_name, decl|
122
+ case decl
123
+ when AST::Declarations::Class
124
+ if list.include?(:class)
125
+ stdout.puts "#{type_name} (class)"
126
+ end
127
+ when AST::Declarations::Module
128
+ if list.include?(:module)
129
+ stdout.puts "#{type_name} (module)"
130
+ end
131
+ when AST::Declarations::Interface
132
+ if list.include?(:interface)
133
+ stdout.puts "#{type_name} (interface)"
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ def run_ancestors(args, options)
140
+ kind = :instance
141
+
142
+ OptionParser.new do |opts|
143
+ opts.on("--instance") { kind = :instance }
144
+ opts.on("--singleton") { kind = :singleton }
145
+ end.order!(args)
146
+
147
+ loader = EnvironmentLoader.new()
148
+
149
+ options.setup(loader)
150
+
151
+ env = Environment.new()
152
+ loader.load(env: env)
153
+
154
+ builder = DefinitionBuilder.new(env: env)
155
+ type_name = parse_type_name(args[0]).absolute!
156
+
157
+ if env.class?(type_name)
158
+ ancestor = case kind
159
+ when :instance
160
+ decl = env.find_class(type_name)
161
+ Definition::Ancestor::Instance.new(name: type_name,
162
+ args: Types::Variable.build(decl.type_params.each.map(&:name)))
163
+ when :singleton
164
+ Definition::Ancestor::Singleton.new(name: type_name)
165
+ end
166
+
167
+ ancestors = builder.build_ancestors(ancestor)
168
+
169
+ ancestors.each do |ancestor|
170
+ case ancestor
171
+ when Definition::Ancestor::Singleton
172
+ stdout.puts "singleton(#{ancestor.name})"
173
+ when Definition::Ancestor::ExtensionSingleton
174
+ stdout.puts "singleton(#{ancestor.name} (#{ancestor.extension_name}))"
175
+ when Definition::Ancestor::Instance
176
+ if ancestor.args.empty?
177
+ stdout.puts ancestor.name.to_s
178
+ else
179
+ stdout.puts "#{ancestor.name}[#{ancestor.args.join(", ")}]"
180
+ 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
+ end
188
+ end
189
+ else
190
+ stdout.puts "Cannot find class: #{type_name}"
191
+ end
192
+ end
193
+
194
+ def run_methods(args, options)
195
+ kind = :instance
196
+ inherit = true
197
+
198
+ OptionParser.new do |opts|
199
+ opts.on("--instance") { kind = :instance }
200
+ opts.on("--singleton") { kind = :singleton }
201
+ opts.on("--inherit") { inherit = true }
202
+ opts.on("--no-inherit") { inherit = false }
203
+ end.order!(args)
204
+
205
+ unless args.size == 1
206
+ stdout.puts "Expected one argument."
207
+ return
208
+ end
209
+
210
+ loader = EnvironmentLoader.new()
211
+
212
+ options.setup(loader)
213
+
214
+ env = Environment.new()
215
+ loader.load(env: env)
216
+
217
+ builder = DefinitionBuilder.new(env: env)
218
+ type_name = parse_type_name(args[0]).absolute!
219
+
220
+ if env.class?(type_name)
221
+ definition = case kind
222
+ when :instance
223
+ builder.build_instance(type_name)
224
+ when :singleton
225
+ builder.build_singleton(type_name)
226
+ end
227
+
228
+ definition.methods.keys.sort.each do |name|
229
+ method = definition.methods[name]
230
+ if inherit || method.implemented_in == definition.declaration
231
+ stdout.puts "#{name} (#{method.accessibility})"
232
+ end
233
+ end
234
+ else
235
+ stdout.puts "Cannot find class: #{type_name}"
236
+ end
237
+ end
238
+
239
+ def run_method(args, options)
240
+ kind = :instance
241
+
242
+ OptionParser.new do |opts|
243
+ opts.on("--instance") { kind = :instance }
244
+ opts.on("--singleton") { kind = :singleton }
245
+ end.order!(args)
246
+
247
+ unless args.size == 2
248
+ stdout.puts "Expected two arguments, but given #{args.size}."
249
+ return
250
+ end
251
+
252
+ loader = EnvironmentLoader.new()
253
+
254
+ options.setup(loader)
255
+
256
+ env = Environment.new()
257
+ loader.load(env: env)
258
+
259
+ builder = DefinitionBuilder.new(env: env)
260
+ type_name = parse_type_name(args[0]).absolute!
261
+ method_name = args[1].to_sym
262
+
263
+ unless env.class?(type_name)
264
+ stdout.puts "Cannot find class: #{type_name}"
265
+ return
266
+ end
267
+
268
+ definition = case kind
269
+ when :instance
270
+ builder.build_instance(type_name)
271
+ when :singleton
272
+ builder.build_singleton(type_name)
273
+ end
274
+
275
+ method = definition.methods[method_name]
276
+
277
+ unless method
278
+ stdout.puts "Cannot find method: #{method_name}"
279
+ return
280
+ end
281
+
282
+ stdout.puts "#{type_name}#{kind == :instance ? "#" : "."}#{method_name}"
283
+ stdout.puts " defined_in: #{method.defined_in&.name&.absolute!}"
284
+ stdout.puts " implementation: #{method.implemented_in.name.absolute!}"
285
+ stdout.puts " accessibility: #{method.accessibility}"
286
+ stdout.puts " types:"
287
+ separator = " "
288
+ for type in method.method_types
289
+ stdout.puts " #{separator} #{type}"
290
+ separator = "|"
291
+ end
292
+ end
293
+
294
+ def run_validate(args, options)
295
+ loader = EnvironmentLoader.new()
296
+
297
+ options.setup(loader)
298
+
299
+ env = Environment.new()
300
+ loader.load(env: env)
301
+
302
+ builder = DefinitionBuilder.new(env: env)
303
+
304
+ env.each_decl do |name, decl|
305
+ case decl
306
+ when AST::Declarations::Class, AST::Declarations::Module
307
+ stdout.puts "#{Location.to_string decl.location}:\tValidating class/module definition: `#{name}`..."
308
+ builder.build_instance(decl.name.absolute!).each_type do |type|
309
+ env.validate type, namespace: Namespace.root
310
+ end
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
319
+ end
320
+ end
321
+
322
+ env.each_constant do |name, const|
323
+ stdout.puts "#{Location.to_string const.location}:\tValidating constant: `#{name}`..."
324
+ env.validate const.type, namespace: name.namespace
325
+ end
326
+
327
+ env.each_global do |name, global|
328
+ stdout.puts "#{Location.to_string global.location}:\tValidating global: `#{name}`..."
329
+ env.validate global.type, namespace: Namespace.root
330
+ end
331
+
332
+ env.each_alias do |name, decl|
333
+ stdout.puts "#{Location.to_string decl.location}:\tValidating alias: `#{name}`..."
334
+ env.validate decl.type, namespace: name.namespace
335
+ end
336
+ end
337
+
338
+ def run_constant(args, options)
339
+ context = nil
340
+
341
+ OptionParser.new do |opts|
342
+ opts.on("--context CONTEXT") {|c| context = c }
343
+ end.order!(args)
344
+
345
+ unless args.size == 1
346
+ stdout.puts "Expected one argument."
347
+ return
348
+ end
349
+
350
+ loader = EnvironmentLoader.new()
351
+
352
+ options.setup(loader)
353
+
354
+ env = Environment.new()
355
+ loader.load(env: env)
356
+
357
+ builder = DefinitionBuilder.new(env: env)
358
+ table = ConstantTable.new(builder: builder)
359
+
360
+ namespace = context ? Namespace.parse(context).absolute! : Namespace.root
361
+ stdout.puts "Context: #{namespace}"
362
+ name = Namespace.parse(args[0]).to_type_name
363
+ stdout.puts "Constant name: #{name}"
364
+
365
+ constant = table.resolve_constant_reference(name, context: namespace)
366
+
367
+ if constant
368
+ stdout.puts " => #{constant.name}: #{constant.type}"
369
+ else
370
+ stdout.puts " => [no constant]"
371
+ end
372
+ end
373
+
374
+ def run_version(args, options)
375
+ stdout.puts "ruby-signature #{VERSION}"
376
+ end
377
+
378
+ def run_paths(args, options)
379
+ loader = EnvironmentLoader.new()
380
+
381
+ options.setup(loader)
382
+
383
+ kind_of = -> (path) {
384
+ case
385
+ when path.file?
386
+ "file"
387
+ when path.directory?
388
+ "dir"
389
+ when !path.exist?
390
+ "absent"
391
+ else
392
+ "unknown"
393
+ end
394
+ }
395
+
396
+ if loader.stdlib_root
397
+ path = loader.stdlib_root
398
+ stdout.puts "#{path}/builtin (#{kind_of[path]}, stdlib)"
399
+ end
400
+
401
+ loader.paths.each do |path|
402
+ case path
403
+ when Pathname
404
+ stdout.puts "#{path} (#{kind_of[path]})"
405
+ when EnvironmentLoader::GemPath
406
+ stdout.puts "#{path.path} (#{kind_of[path.path]}, gem, name=#{path.name}, version=#{path.version})"
407
+ when EnvironmentLoader::LibraryPath
408
+ stdout.puts "#{path.path} (#{kind_of[path.path]}, library, name=#{path.name})"
409
+ end
410
+ end
411
+ end
412
+
413
+ def run_prototype(args, options)
414
+ format = args.shift
415
+
416
+ case format
417
+ when "rbi", "rb"
418
+ decls = run_prototype_file(format, args)
419
+ when "runtime"
420
+ require_libs = []
421
+ relative_libs = []
422
+ merge = false
423
+ owners_included = []
424
+
425
+ OptionParser.new do |opts|
426
+ opts.on("--require LIB") do |lib|
427
+ require_libs << lib
428
+ end
429
+ opts.on("--require-relative LIB") do |lib|
430
+ relative_libs << lib
431
+ end
432
+ opts.on("--merge") do
433
+ merge = true
434
+ end
435
+ opts.on("--method-owner CLASS") do |klass|
436
+ owners_included << klass
437
+ end
438
+ end.parse!(args)
439
+
440
+ loader = EnvironmentLoader.new()
441
+
442
+ options.setup(loader)
443
+
444
+ env = Environment.new()
445
+ loader.load(env: env)
446
+
447
+ require_libs.each do |lib|
448
+ require(lib)
449
+ end
450
+
451
+ relative_libs.each do |lib|
452
+ require(lib)
453
+ end
454
+
455
+ decls = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included).decls
456
+ else
457
+ stdout.puts "Supported formats: rbi, rb, runtime"
458
+ exit 1
459
+ end
460
+
461
+ writer = Writer.new(out: stdout)
462
+ writer.write decls
463
+ end
464
+
465
+ def run_prototype_file(format, args)
466
+ parser = case format
467
+ when "rbi"
468
+ Prototype::RBI.new()
469
+ when "rb"
470
+ Prototype::RB.new()
471
+ end
472
+
473
+ args.each do |file|
474
+ parser.parse Pathname(file).read
475
+ end
476
+
477
+ parser.decls
478
+ end
479
+
480
+ def run_vendor(args, options)
481
+ clean = false
482
+ vendor_stdlib = false
483
+ vendor_dir = Pathname("vendor/sigs")
484
+
485
+ OptionParser.new do |opts|
486
+ opts.banner = <<~EOB
487
+ Usage: rbs vendor [options] GEMS...
488
+ Vendor signatures in the project directory.
489
+ EOB
490
+
491
+ opts.on("--[no-]clean", "Clean vendor directory (default: no)") do |v|
492
+ clean = v
493
+ end
494
+
495
+ opts.on("--[no-]stdlib", "Vendor stdlib signatures or not (default: no)") do |v|
496
+ vendor_stdlib = v
497
+ end
498
+
499
+ opts.on("--vendor-dir [DIR]", "Specify the directory for vendored signatures (default: vendor/sigs)") do |path|
500
+ vendor_dir = Pathname(path)
501
+ end
502
+ end.parse!(args)
503
+
504
+ stdout.puts "Vendoring signatures to #{vendor_dir}..."
505
+
506
+ vendorer = Vendorer.new(vendor_dir: vendor_dir)
507
+
508
+ if clean
509
+ stdout.puts " Deleting #{vendor_dir}..."
510
+ vendorer.clean!
511
+ end
512
+
513
+ if vendor_stdlib
514
+ stdout.puts " Vendoring standard libraries..."
515
+ vendorer.stdlib!
516
+ end
517
+
518
+ args.each do |gem|
519
+ name, version = EnvironmentLoader.parse_library(gem)
520
+
521
+ unless EnvironmentLoader.gem_sig_path(name, version)
522
+ stdout.puts " ⚠️ Cannot find rubygem: name=#{name}, version=#{version} 🚨"
523
+ else
524
+ stdout.puts " Vendoring gem: name=#{name}, version=#{version}..."
525
+ vendorer.gem!(name, version)
526
+ end
527
+ end
528
+ end
529
+
530
+ def run_parse(args, options)
531
+ loader = EnvironmentLoader.new()
532
+
533
+ syntax_error = false
534
+ args.each do |path|
535
+ path = Pathname(path)
536
+ loader.each_signature(path) do |sig_path|
537
+ Parser.parse_signature(sig_path.read)
538
+ rescue RBS::Parser::SyntaxError => ex
539
+ loc = ex.error_value.location
540
+ stdout.puts "#{sig_path}:#{loc.start_line}:#{loc.start_column}: parse error on value: (#{ex.token_str})"
541
+ syntax_error = true
542
+ rescue RBS::Parser::SemanticsError => ex
543
+ loc = ex.location
544
+ stdout.puts "#{sig_path}:#{loc.start_line}:#{loc.start_column}: #{ex.original_message}"
545
+ syntax_error = true
546
+ end
547
+ end
548
+ exit 1 if syntax_error
549
+ end
550
+
551
+ def parse_type_name(string)
552
+ Namespace.parse(string).yield_self do |namespace|
553
+ last = namespace.path.last
554
+ TypeName.new(name: last, namespace: namespace.parent)
555
+ end
556
+ end
557
+ end
558
+ end