rbs 3.2.2 → 3.3.0.pre.1

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 (125) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/comments.yml +1 -1
  3. data/.github/workflows/ruby.yml +7 -2
  4. data/CHANGELOG.md +85 -0
  5. data/Gemfile.lock +14 -14
  6. data/README.md +11 -2
  7. data/Rakefile +10 -7
  8. data/Steepfile +7 -7
  9. data/core/basic_object.rbs +7 -7
  10. data/core/binding.rbs +3 -3
  11. data/core/builtin.rbs +171 -5
  12. data/core/constants.rbs +17 -17
  13. data/core/dir.rbs +3 -3
  14. data/core/encoding.rbs +434 -628
  15. data/core/enumerator.rbs +37 -0
  16. data/core/exception.rbs +11 -11
  17. data/core/false_class.rbs +5 -11
  18. data/core/fiber.rbs +3 -3
  19. data/core/file_test.rbs +28 -26
  20. data/core/kernel.rbs +900 -21
  21. data/core/marshal.rbs +24 -14
  22. data/core/match_data.rbs +8 -8
  23. data/core/math.rbs +57 -53
  24. data/core/method.rbs +3 -1
  25. data/core/module.rbs +38 -36
  26. data/core/nil_class.rbs +7 -13
  27. data/core/object.rbs +3 -966
  28. data/core/process.rbs +3 -3
  29. data/core/ractor.rbs +2 -2
  30. data/core/rb_config.rbs +64 -43
  31. data/core/regexp.rbs +3 -3
  32. data/core/signal.rbs +10 -4
  33. data/core/struct.rbs +1 -1
  34. data/core/thread.rbs +7 -7
  35. data/core/thread_group.rbs +9 -9
  36. data/core/true_class.rbs +5 -11
  37. data/core/unbound_method.rbs +56 -7
  38. data/core/warning.rbs +33 -0
  39. data/docs/collection.md +56 -6
  40. data/docs/data_and_struct.md +57 -0
  41. data/docs/stdlib.md +61 -2
  42. data/docs/syntax.md +123 -2
  43. data/ext/rbs_extension/lexer.c +624 -569
  44. data/ext/rbs_extension/lexer.h +1 -0
  45. data/ext/rbs_extension/lexer.re +1 -0
  46. data/ext/rbs_extension/lexstate.c +1 -0
  47. data/ext/rbs_extension/parser.c +6 -0
  48. data/goodcheck.yml +2 -2
  49. data/lib/rbs/annotate/formatter.rb +13 -3
  50. data/lib/rbs/annotate/rdoc_source.rb +10 -1
  51. data/lib/rbs/cli/colored_io.rb +48 -0
  52. data/lib/rbs/cli/diff.rb +80 -0
  53. data/lib/rbs/cli.rb +151 -16
  54. data/lib/rbs/collection/config/lockfile.rb +0 -25
  55. data/lib/rbs/collection/config/lockfile_generator.rb +0 -6
  56. data/lib/rbs/collection/installer.rb +1 -1
  57. data/lib/rbs/collection/sources/git.rb +6 -4
  58. data/lib/rbs/collection/sources/local.rb +7 -5
  59. data/lib/rbs/diff.rb +104 -0
  60. data/lib/rbs/environment.rb +1 -1
  61. data/lib/rbs/method_type.rb +23 -0
  62. data/lib/rbs/prototype/rb.rb +2 -9
  63. data/lib/rbs/prototype/runtime/helpers.rb +59 -0
  64. data/lib/rbs/prototype/runtime/value_object_generator.rb +236 -0
  65. data/lib/rbs/prototype/runtime.rb +234 -150
  66. data/lib/rbs/sorter.rb +144 -117
  67. data/lib/rbs/test/guaranteed.rb +31 -0
  68. data/lib/rbs/test/type_check.rb +4 -4
  69. data/lib/rbs/test.rb +3 -0
  70. data/lib/rbs/types.rb +184 -3
  71. data/lib/rbs/version.rb +1 -1
  72. data/lib/rbs/writer.rb +4 -4
  73. data/lib/rbs.rb +1 -0
  74. data/rbs.gemspec +1 -0
  75. data/sig/annotate/formatter.rbs +2 -2
  76. data/sig/annotate/rdoc_annotater.rbs +1 -1
  77. data/sig/cli/colored_io.rbs +15 -0
  78. data/sig/cli/diff.rbs +21 -0
  79. data/sig/cli.rbs +2 -0
  80. data/sig/collection/config/lockfile.rbs +0 -6
  81. data/sig/diff.rbs +23 -0
  82. data/sig/errors.rbs +1 -5
  83. data/sig/method_types.rbs +6 -0
  84. data/sig/prototype/runtime.rbs +108 -0
  85. data/sig/rdoc/rbs.rbs +4 -0
  86. data/sig/shims/bundler.rbs +5 -0
  87. data/sig/sorter.rbs +23 -5
  88. data/sig/types.rbs +29 -0
  89. data/stdlib/benchmark/0/benchmark.rbs +1 -1
  90. data/stdlib/cgi/0/core.rbs +2 -2
  91. data/stdlib/did_you_mean/0/did_you_mean.rbs +2 -2
  92. data/stdlib/digest/0/digest.rbs +1 -1
  93. data/stdlib/fileutils/0/fileutils.rbs +1 -1
  94. data/stdlib/forwardable/0/forwardable.rbs +4 -4
  95. data/stdlib/io-console/0/io-console.rbs +1 -1
  96. data/stdlib/json/0/json.rbs +37 -0
  97. data/stdlib/logger/0/logger.rbs +2 -2
  98. data/stdlib/net-http/0/manifest.yaml +1 -1
  99. data/stdlib/net-http/0/net-http.rbs +16 -63
  100. data/stdlib/net-protocol/0/manifest.yaml +2 -0
  101. data/stdlib/net-protocol/0/net-protocol.rbs +56 -0
  102. data/stdlib/openssl/0/openssl.rbs +1 -1
  103. data/stdlib/pp/0/manifest.yaml +2 -0
  104. data/stdlib/pp/0/pp.rbs +301 -0
  105. data/stdlib/{yaml → psych}/0/dbm.rbs +3 -3
  106. data/stdlib/psych/0/manifest.yaml +3 -0
  107. data/stdlib/psych/0/psych.rbs +391 -0
  108. data/stdlib/{yaml → psych}/0/store.rbs +2 -2
  109. data/stdlib/rdoc/0/code_object.rbs +55 -0
  110. data/stdlib/rdoc/0/comment.rbs +60 -0
  111. data/stdlib/rdoc/0/context.rbs +153 -0
  112. data/stdlib/rdoc/0/markup.rbs +119 -0
  113. data/stdlib/rdoc/0/parser.rbs +56 -0
  114. data/stdlib/rdoc/0/rdoc.rbs +0 -372
  115. data/stdlib/rdoc/0/ri.rbs +17 -0
  116. data/stdlib/rdoc/0/store.rbs +48 -0
  117. data/stdlib/rdoc/0/top_level.rbs +97 -0
  118. data/stdlib/socket/0/basic_socket.rbs +1 -1
  119. data/stdlib/socket/0/socket.rbs +1 -1
  120. data/stdlib/uri/0/common.rbs +1 -1
  121. data/stdlib/yaml/0/manifest.yaml +1 -2
  122. data/stdlib/yaml/0/yaml.rbs +1 -199
  123. metadata +46 -9
  124. data/sig/shims/pp.rbs +0 -3
  125. data/sig/shims.rbs +0 -47
@@ -60,6 +60,7 @@ enum TokenType {
60
60
  kVOID, /* void */
61
61
  kUSE, /* use */
62
62
  kAS, /* as */
63
+ k__TODO__, /* __todo__ */
63
64
 
64
65
  tLIDENT, /* Identifiers starting with lower case */
65
66
  tUIDENT, /* Identifiers starting with upper case */
@@ -95,6 +95,7 @@ start:
95
95
  "void" { return next_token(state, kVOID); }
96
96
  "use" { return next_token(state, kUSE); }
97
97
  "as" { return next_token(state, kAS); }
98
+ "__todo__" { return next_token(state, k__TODO__); }
98
99
 
99
100
  dqstring = ["] ("\\"[abefnrstv"\\] | [^"\\\x00])* ["];
100
101
  sqstring = ['] ("\\"['\\] | [^'\x00])* ['];
@@ -59,6 +59,7 @@ static const char *RBS_TOKENTYPE_NAMES[] = {
59
59
  "kVOID", /* void */
60
60
  "kUSE", /* use */
61
61
  "kAS", /* as */
62
+ "k__TODO__", /* __todo__ */
62
63
 
63
64
  "tLIDENT", /* Identifiers starting with lower case */
64
65
  "tUIDENT", /* Identifiers starting with upper case */
@@ -39,6 +39,7 @@
39
39
  case kUNTYPED: \
40
40
  case kUSE: \
41
41
  case kAS: \
42
+ case k__TODO__: \
42
43
  /* nop */
43
44
 
44
45
  typedef struct {
@@ -898,6 +899,11 @@ static VALUE parse_simple(parserstate *state) {
898
899
  return rbs_base_type(RBS_Types_Bases_Void, rbs_location_current_token(state));
899
900
  case kUNTYPED:
900
901
  return rbs_base_type(RBS_Types_Bases_Any, rbs_location_current_token(state));
902
+ case k__TODO__: {
903
+ VALUE type = rbs_base_type(RBS_Types_Bases_Any, rbs_location_current_token(state));
904
+ rb_funcall(type, rb_intern("todo!"), 0);
905
+ return type;
906
+ }
901
907
  case tINTEGER: {
902
908
  VALUE literal = rb_funcall(
903
909
  string_of_loc(state, state->current_token.range.start, state->current_token.range.end),
data/goodcheck.yml CHANGED
@@ -13,9 +13,9 @@ rules:
13
13
  glob:
14
14
  - "{core,stdlib}/**/*.rbs"
15
15
  fail:
16
- - "def `send`: (String | Symbol arg0, *untyped arg1) -> untyped"
16
+ - "def `send`: (interned arg0, *untyped arg1) -> untyped"
17
17
  pass:
18
- - "def `send`: (String | Symbol, *untyped) -> untyped"
18
+ - "def `send`: (interned, *untyped) -> untyped"
19
19
 
20
20
  - id: rbs.prefer_boolish
21
21
  pattern:
@@ -59,10 +59,20 @@ module RBS
59
59
 
60
60
  def self.each_part(doc, &block)
61
61
  if block
62
- if doc.file
63
- yield doc
62
+ document =
63
+ case doc
64
+ when String
65
+ raise
66
+ when RDoc::Comment
67
+ document = doc.parse
68
+ when RDoc::Markup::Document
69
+ document = doc
70
+ end
71
+
72
+ if document.file
73
+ yield document
64
74
  else
65
- doc.each do |d|
75
+ document.each do |d|
66
76
  each_part(d, &block)
67
77
  end
68
78
  end
@@ -47,7 +47,16 @@ module RBS
47
47
  def docs
48
48
  if ds = yield
49
49
  unless ds.empty?
50
- ds.map(&:comment)
50
+ ds.map do |code_object|
51
+ case comment = code_object.comment
52
+ when String
53
+ raise
54
+ when RDoc::Comment
55
+ comment.parse
56
+ when RDoc::Markup::Document
57
+ comment
58
+ end
59
+ end
51
60
  end
52
61
  end
53
62
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ class CLI
5
+ class ColoredIO
6
+ attr_reader :stdout
7
+
8
+ def initialize(stdout:)
9
+ @stdout = stdout
10
+ end
11
+
12
+ def puts_red(string)
13
+ if can_display_colors?
14
+ puts "\e[31m#{string}\e[m"
15
+ else
16
+ puts string
17
+ end
18
+ end
19
+
20
+ def puts_green(string)
21
+ if can_display_colors?
22
+ puts "\e[32m#{string}\e[m"
23
+ else
24
+ puts string
25
+ end
26
+ end
27
+
28
+ def puts(...)
29
+ stdout.puts(...)
30
+ end
31
+
32
+ private
33
+
34
+ # https://github.com/rubygems/rubygems/blob/ed65279100234a17d65d71fe26de5083984ac5b8/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb#L99-L109
35
+ def can_display_colors?
36
+ are_colors_supported? && !are_colors_disabled?
37
+ end
38
+
39
+ def are_colors_supported?
40
+ stdout.tty? && ENV["TERM"] != "dumb"
41
+ end
42
+
43
+ def are_colors_disabled?
44
+ !ENV['NO_COLOR'].nil? && !ENV.fetch('NO_COLOR', '').empty?
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ class CLI
5
+ class Diff
6
+ def initialize(argv:, library_options:, stdout: $stdout, stderr: $stderr)
7
+ @format = nil
8
+ @stdout = stdout
9
+ @stderr = stderr
10
+
11
+ # @type var type_name: String?
12
+ type_name = nil
13
+ library_options = library_options
14
+ before_path = []
15
+ after_path = []
16
+
17
+ opt = OptionParser.new do |o|
18
+ o.banner = <<~HELP
19
+ [Experimental] This command is experimental. API and output compatibility is not guaranteed.
20
+
21
+ Usage:
22
+ rbs diff --format markdown --type-name Foo --before before_sig --after after_sig
23
+
24
+ Print diff for rbs environment dir
25
+
26
+ Examples:
27
+
28
+ # Diff dir1 and dir2 for Foo
29
+ $ rbs diff --format markdown --type-name Foo --before dir1 --after dir2
30
+
31
+ # Confirmation of methods related to Time class added by including stdlib/time
32
+ $ rbs diff --format diff --type-name Time --after stdlib/time
33
+ HELP
34
+ o.on("--format NAME") { |arg| @format = arg }
35
+ o.on("--type-name NAME") { |arg| type_name = arg }
36
+ o.on("--before DIR") { |arg| before_path << arg }
37
+ o.on("--after DIR") { |arg| after_path << arg }
38
+ end
39
+ opt.parse!(argv)
40
+
41
+ unless @format && type_name && ["markdown", "diff"].include?(@format)
42
+ @stderr.puts opt.banner
43
+ exit 1
44
+ end
45
+
46
+ @diff = RBS::Diff.new(
47
+ type_name: TypeName(type_name).absolute!,
48
+ library_options: library_options,
49
+ after_path: after_path,
50
+ before_path: before_path
51
+ )
52
+ end
53
+
54
+ def run
55
+ public_send("run_#{@format}")
56
+ end
57
+
58
+ def run_diff
59
+ first = true
60
+ io = RBS::CLI::ColoredIO.new(stdout: @stdout)
61
+ @diff.each_diff do |before, after|
62
+ io.puts if !first
63
+ io.puts_red "- #{before}"
64
+ io.puts_green "+ #{after}"
65
+ first = false
66
+ end
67
+ end
68
+
69
+ def run_markdown
70
+ @stdout.puts "| before | after |"
71
+ @stdout.puts "| --- | --- |"
72
+ @diff.each_diff do |before, after|
73
+ before.gsub!("|", "\\|")
74
+ after.gsub!("|", "\\|")
75
+ @stdout.puts "| `#{before}` | `#{after}` |"
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
data/lib/rbs/cli.rb CHANGED
@@ -8,6 +8,9 @@ require "stringio"
8
8
 
9
9
  module RBS
10
10
  class CLI
11
+ autoload :ColoredIO, 'rbs/cli/colored_io'
12
+ autoload :Diff, 'rbs/cli/diff'
13
+
11
14
  class LibraryOptions
12
15
  attr_accessor :core_root
13
16
  attr_accessor :config_path
@@ -90,7 +93,7 @@ module RBS
90
93
  @stderr = stderr
91
94
  end
92
95
 
93
- COMMANDS = [:ast, :annotate, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection, :subtract]
96
+ COMMANDS = [:ast, :annotate, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection, :subtract, :diff]
94
97
 
95
98
  def parse_logging_options(opts)
96
99
  opts.on("--log-level LEVEL", "Specify log level (defaults to `warn`)") do |level|
@@ -433,8 +436,9 @@ EOU
433
436
  stdout.puts " accessibility: #{method.accessibility}"
434
437
  stdout.puts " types:"
435
438
  separator = " "
436
- for type in method.method_types
437
- stdout.puts " #{separator} #{type}"
439
+ length_max = method.method_types.map { |type| type.to_s.length }.max or raise
440
+ method.method_types.each do |type|
441
+ stdout.puts format(" %s %-#{length_max}s at %s", separator, type, type.location)
438
442
  separator = "|"
439
443
  end
440
444
  end
@@ -462,6 +466,30 @@ EOU
462
466
  builder = DefinitionBuilder.new(env: env)
463
467
  validator = Validator.new(env: env, resolver: Resolver::TypeNameResolver.new(env))
464
468
 
469
+ no_self_type_validator = ->(type) {
470
+ # @type var type: Types::t | MethodType
471
+ if type.has_self_type?
472
+ raise "#{type.location}: `self` type is not allowed in this context"
473
+ end
474
+ }
475
+
476
+ no_classish_type_validator = ->(type) {
477
+ # @type var type: Types::t | MethodType
478
+ if type.has_classish_type?
479
+ raise "#{type.location}: `instance` or `class` type is not allowed in this context"
480
+ end
481
+ }
482
+
483
+ void_type_context_validator = ->(type, allowed_here = false) {
484
+ # @type var type: Types::t | MethodType
485
+ if allowed_here
486
+ next if type.is_a?(Types::Bases::Void)
487
+ end
488
+ if type.with_nonreturn_void?
489
+ raise "#{type.location}: `void` type is only allowed in return type or generics parameter"
490
+ end
491
+ }
492
+
465
493
  env.class_decls.each do |name, decl|
466
494
  stdout.puts "Validating class/module definition: `#{name}`..."
467
495
  builder.build_instance(name).each_type do |type|
@@ -471,6 +499,29 @@ EOU
471
499
  validator.validate_type type, context: nil
472
500
  end
473
501
 
502
+ case decl
503
+ when Environment::ClassEntry
504
+ decl.decls.each do |decl|
505
+ if super_class = decl.decl.super_class
506
+ super_class.args.each do |arg|
507
+ void_type_context_validator[arg, true]
508
+ no_self_type_validator[arg]
509
+ no_classish_type_validator[arg]
510
+ end
511
+ end
512
+ end
513
+ when Environment::ModuleEntry
514
+ decl.decls.each do |decl|
515
+ decl.decl.self_types.each do |self_type|
516
+ self_type.args.each do |arg|
517
+ void_type_context_validator[arg, true]
518
+ no_self_type_validator[arg]
519
+ no_classish_type_validator[arg]
520
+ end
521
+ end
522
+ end
523
+ end
524
+
474
525
  d = decl.primary.decl
475
526
 
476
527
  validator.validate_type_params(
@@ -479,11 +530,36 @@ EOU
479
530
  location: d.location&.aref(:type_params)
480
531
  )
481
532
 
533
+ d.type_params.each do |param|
534
+ if ub = param.upper_bound
535
+ void_type_context_validator[ub]
536
+ no_self_type_validator[ub]
537
+ no_classish_type_validator[ub]
538
+ end
539
+ end
540
+
482
541
  decl.decls.each do |d|
483
542
  d.decl.each_member do |member|
484
543
  case member
485
544
  when AST::Members::MethodDefinition
486
545
  validator.validate_method_definition(member, type_name: name)
546
+ member.overloads.each do |ov|
547
+ void_type_context_validator[ov.method_type]
548
+ end
549
+ when AST::Members::Attribute
550
+ void_type_context_validator[member.type]
551
+ when AST::Members::Mixin
552
+ member.args.each do |arg|
553
+ no_self_type_validator[arg]
554
+ unless arg.is_a?(Types::Bases::Void)
555
+ void_type_context_validator[arg, true]
556
+ end
557
+ end
558
+ when AST::Members::Var
559
+ void_type_context_validator[member.type]
560
+ if member.is_a?(AST::Members::ClassVariable)
561
+ no_self_type_validator[member.type]
562
+ end
487
563
  end
488
564
  end
489
565
  end
@@ -510,6 +586,10 @@ EOU
510
586
  case member
511
587
  when AST::Members::MethodDefinition
512
588
  validator.validate_method_definition(member, type_name: name)
589
+ member.overloads.each do |ov|
590
+ void_type_context_validator[ov.method_type]
591
+ no_classish_type_validator[ov.method_type]
592
+ end
513
593
  end
514
594
  end
515
595
  end
@@ -518,11 +598,17 @@ EOU
518
598
  stdout.puts "Validating constant: `#{name}`..."
519
599
  validator.validate_type const.decl.type, context: const.context
520
600
  builder.ensure_namespace!(name.namespace, location: const.decl.location)
601
+ no_self_type_validator[const.decl.type]
602
+ no_classish_type_validator[const.decl.type]
603
+ void_type_context_validator[const.decl.type]
521
604
  end
522
605
 
523
606
  env.global_decls.each do |name, global|
524
607
  stdout.puts "Validating global: `#{name}`..."
525
608
  validator.validate_type global.decl.type, context: nil
609
+ no_self_type_validator[global.decl.type]
610
+ no_classish_type_validator[global.decl.type]
611
+ void_type_context_validator[global.decl.type]
526
612
  end
527
613
 
528
614
  env.type_alias_decls.each do |name, decl|
@@ -531,6 +617,9 @@ EOU
531
617
  validator.validate_type type, context: nil
532
618
  end
533
619
  validator.validate_type_alias(entry: decl)
620
+ no_self_type_validator[decl.decl.type]
621
+ no_classish_type_validator[decl.decl.type]
622
+ void_type_context_validator[decl.decl.type]
534
623
  end
535
624
  end
536
625
 
@@ -644,8 +733,10 @@ EOU
644
733
  require_libs = []
645
734
  relative_libs = []
646
735
  merge = false
736
+ todo = false
647
737
  owners_included = []
648
738
  outline = false
739
+ autoload = false
649
740
 
650
741
  OptionParser.new do |opts|
651
742
  opts.banner = <<EOU
@@ -671,26 +762,62 @@ EOU
671
762
  opts.on("--merge", "Merge generated prototype RBS with existing RBS") do
672
763
  merge = true
673
764
  end
765
+ opts.on("--todo", "Generates only undefined methods compared to objects") do
766
+ Warning.warn("Geneating prototypes with `--todo` option is experimental\n", category: :experimental)
767
+ todo = true
768
+ end
674
769
  opts.on("--method-owner CLASS", "Generate method prototypes if the owner of the method is [CLASS]") do |klass|
675
770
  owners_included << klass
676
771
  end
677
772
  opts.on("--outline", "Generates only module/class/constant declaration (no method definition)") do
678
773
  outline = true
679
774
  end
775
+ opts.on("--autoload", "Load all autoload path") do
776
+ autoload = true
777
+ end
680
778
  end.parse!(args)
681
779
 
682
780
  loader = options.loader()
683
781
  env = Environment.from_loader(loader).resolve_type_names
684
782
 
685
- require_libs.each do |lib|
686
- require(lib)
687
- end
688
-
689
- relative_libs.each do |lib|
690
- eval("require_relative(lib)", binding, "rbs")
783
+ # @type var autoloader: ^() { () -> void } -> void
784
+ autoloader = ->(&block) {
785
+ if autoload
786
+ hook = Module.new do
787
+ def autoload(name, path)
788
+ super
789
+ end
790
+ end
791
+ ::Module.prepend(hook)
792
+ ::Kernel.prepend(hook)
793
+
794
+ arguments = []
795
+ TracePoint.new(:call) do |tp|
796
+ base = tp.self.kind_of?(Module) ? tp.self : Kernel
797
+ name = (tp.binding or raise).local_variable_get(:name)
798
+ arguments << [base, name]
799
+ end.enable(target: hook.instance_method(:autoload), &block)
800
+
801
+ arguments.each do |(base, name)|
802
+ begin
803
+ base.const_get(name)
804
+ rescue LoadError, StandardError
805
+ end
806
+ end
807
+ else
808
+ block.call
809
+ end
810
+ }
811
+ autoloader.call do
812
+ require_libs.each do |lib|
813
+ require(lib)
814
+ end
815
+ relative_libs.each do |lib|
816
+ eval("require_relative(lib)", binding, "rbs")
817
+ end
691
818
  end
692
819
 
693
- runtime = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included)
820
+ runtime = Prototype::Runtime.new(patterns: args, env: env, merge: merge, todo: todo, owners_included: owners_included)
694
821
  runtime.outline = outline
695
822
 
696
823
  decls = runtime.decls
@@ -827,7 +954,12 @@ EOU
827
954
  output_path = (output_dir + relative_path).sub_ext(".rbs")
828
955
 
829
956
  parser = new_parser[]
830
- parser.parse file_path.read()
957
+ begin
958
+ parser.parse file_path.read()
959
+ rescue SyntaxError
960
+ stdout.puts " ⚠️ Unable to parse due to SyntaxError: `#{file_path}`"
961
+ next
962
+ end
831
963
 
832
964
  if output_path.file?
833
965
  if force
@@ -1136,11 +1268,10 @@ EOB
1136
1268
  # A directory to install the downloaded RBSs
1137
1269
  path: .gem_rbs_collection
1138
1270
 
1139
- gems:
1140
- # Skip loading rbs gem's RBS.
1141
- # It's unnecessary if you don't use rbs as a library.
1142
- - name: rbs
1143
- ignore: true
1271
+ # gems:
1272
+ # # If you want to avoid installing rbs files for gems, you can specify them here.
1273
+ # - name: GEM_NAME
1274
+ # ignore: true
1144
1275
  YAML
1145
1276
  stdout.puts "created: #{config_path}"
1146
1277
  when 'clean'
@@ -1259,5 +1390,9 @@ EOB
1259
1390
  end
1260
1391
  end
1261
1392
  end
1393
+
1394
+ def run_diff(argv, library_options)
1395
+ Diff.new(argv: argv, library_options: library_options, stdout: stdout, stderr: stderr).run
1396
+ end
1262
1397
  end
1263
1398
  end
@@ -12,7 +12,6 @@ module RBS
12
12
  @path = path
13
13
  @gemfile_lock_path = gemfile_lock_path
14
14
 
15
- @sources = {}
16
15
  @gems = {}
17
16
  end
18
17
 
@@ -26,27 +25,15 @@ module RBS
26
25
  end
27
26
  end
28
27
 
29
- def each_source(&block)
30
- if block
31
- sources.each_value(&block)
32
- yield Sources::Rubygems.instance
33
- yield Sources::Stdlib.instance
34
- else
35
- enum_for :each_source
36
- end
37
- end
38
-
39
28
  def to_lockfile
40
29
  # @type var data: lockfile_data
41
30
 
42
31
  data = {
43
- "sources" => sources.each_value.sort_by {|s| s.name }.map {|source| source.to_lockfile },
44
32
  "path" => path.to_s,
45
33
  "gems" => gems.each_value.sort_by {|g| g[:name] }.map {|hash| library_data(hash) },
46
34
  "gemfile_lock_path" => gemfile_lock_path.to_s
47
35
  }
48
36
 
49
- data.delete("sources") if sources.empty?
50
37
  data.delete("gems") if gems.empty?
51
38
 
52
39
  data
@@ -60,18 +47,6 @@ module RBS
60
47
 
61
48
  lockfile = Lockfile.new(lockfile_path: lockfile_path, path: path, gemfile_lock_path: gemfile_lock_path)
62
49
 
63
- if sources = data["sources"]
64
- sources.each do |src|
65
- git = Sources::Git.new(
66
- name: src["name"],
67
- revision: src["revision"],
68
- remote: src["remote"],
69
- repo_dir: src["repo_dir"]
70
- )
71
- lockfile.sources[git.name] = git
72
- end
73
- end
74
-
75
50
  if gems = data["gems"]
76
51
  gems.each do |gem|
77
52
  src = gem["source"]
@@ -44,12 +44,6 @@ module RBS
44
44
  path: config.repo_path_data,
45
45
  gemfile_lock_path: definition.lockfile.relative_path_from(lockfile_dir)
46
46
  )
47
- config.sources.each do |source|
48
- case source
49
- when Sources::Git
50
- lockfile.sources[source.name] = source
51
- end
52
- end
53
47
 
54
48
  if with_lockfile && lockfile_path.file?
55
49
  @existing_lockfile = Lockfile.from_lockfile(lockfile_path: lockfile_path, data: YAML.load_file(lockfile_path.to_s))
@@ -25,7 +25,7 @@ module RBS
25
25
  stdout: stdout
26
26
  )
27
27
  end
28
- stdout.puts "It's done! #{selected.size} gems' RBSs now installed."
28
+ CLI::ColoredIO.new(stdout: stdout).puts_green("It's done! #{selected.size} gems' RBSs now installed.")
29
29
  end
30
30
  end
31
31
  end
@@ -45,23 +45,25 @@ module RBS
45
45
 
46
46
  gem_dir = dest.join(name, version)
47
47
 
48
+ colored_io = CLI::ColoredIO.new(stdout: stdout)
49
+
48
50
  case
49
51
  when gem_dir.symlink?
50
- stdout.puts "Updating to #{format_config_entry(name, version)} from a local source"
52
+ colored_io.puts_green("Updating to #{format_config_entry(name, version)} from a local source")
51
53
  gem_dir.unlink
52
54
  _install(dest: dest, name: name, version: version)
53
55
  when gem_dir.directory?
54
56
  prev = load_metadata(dir: gem_dir)
55
57
 
56
58
  if prev == metadata_content(name: name, version: version)
57
- stdout.puts "Using #{format_config_entry(name, version)}"
59
+ colored_io.puts "Using #{format_config_entry(name, version)}"
58
60
  else
59
- stdout.puts "Updating to #{format_config_entry(name, version)} from #{format_config_entry(prev["name"], prev["version"])}"
61
+ colored_io.puts_green("Updating to #{format_config_entry(name, version)} from #{format_config_entry(prev["name"], prev["version"])}")
60
62
  FileUtils.remove_entry_secure(gem_dir.to_s)
61
63
  _install(dest: dest, name: name, version: version)
62
64
  end
63
65
  when !gem_dir.exist?
64
- stdout.puts "Installing #{format_config_entry(name, version)}"
66
+ colored_io.puts_green("Installing #{format_config_entry(name, version)}")
65
67
  _install(dest: dest, name: name, version: version)
66
68
  else
67
69
  raise
@@ -7,7 +7,7 @@ module RBS
7
7
  include Base
8
8
 
9
9
  attr_reader :path, :full_path
10
-
10
+
11
11
  def initialize(path:, base_directory:)
12
12
  # TODO: resolve relative path from dir of rbs_collection.yaml
13
13
  @path = Pathname(path)
@@ -33,22 +33,24 @@ module RBS
33
33
  from = @full_path.join(name, version)
34
34
  gem_dir = dest.join(name, version)
35
35
 
36
+ colored_io = CLI::ColoredIO.new(stdout: stdout)
37
+
36
38
  case
37
39
  when gem_dir.symlink? && gem_dir.readlink == from
38
- stdout.puts "Using #{name}:#{version} (#{from})"
40
+ colored_io.puts "Using #{name}:#{version} (#{from})"
39
41
  when gem_dir.symlink?
40
42
  prev = gem_dir.readlink
41
43
  gem_dir.unlink
42
44
  _install(from, dest.join(name, version))
43
- stdout.puts "Updating #{name}:#{version} to #{from} from #{prev}"
45
+ colored_io.puts_green("Updating #{name}:#{version} to #{from} from #{prev}")
44
46
  when gem_dir.directory?
45
47
  # TODO: Show version of git source
46
48
  FileUtils.remove_entry_secure(gem_dir.to_s)
47
49
  _install(from, dest.join(name, version))
48
- stdout.puts "Updating #{name}:#{version} from git source"
50
+ colored_io.puts_green("Updating #{name}:#{version} from git source")
49
51
  when !gem_dir.exist?
50
52
  _install(from, dest.join(name, version))
51
- stdout.puts "Installing #{name}:#{version} (#{from})"
53
+ colored_io.puts_green("Installing #{name}:#{version} (#{from})")
52
54
  else
53
55
  raise
54
56
  end