rbs 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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