rbs 2.4.0 → 2.5.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.
@@ -69,7 +69,8 @@ enum TokenType {
69
69
  tBANGIDENT, /* Identifiers ending with `!` */
70
70
  tEQIDENT, /* Identifiers ending with `=` */
71
71
  tQIDENT, /* Quoted identifier */
72
- tOPERATOR, /* Operator identifier */
72
+ pAREF_OPR, /* [] */
73
+ tOPERATOR, /* Operator identifier */
73
74
 
74
75
  tCOMMENT, /* Comment */
75
76
  tLINECOMMENT, /* Comment of all line */
@@ -19,7 +19,7 @@ start:
19
19
 
20
20
  word = [a-zA-Z0-9_];
21
21
 
22
- operator = "/" | "~" | "[]" | "[]=" | "!" | "!=" | "!~" | "-" | "-@" | "+" | "+@"
22
+ operator = "/" | "~" | "[]=" | "!" | "!=" | "!~" | "-" | "-@" | "+" | "+@"
23
23
  | "==" | "===" | "=~" | "<<" | "<=" | "<=>" | ">" | ">=" | ">>" | "%";
24
24
 
25
25
  "(" { return next_token(state, pLPAREN); }
@@ -45,6 +45,7 @@ start:
45
45
  ":" { return next_token(state, pCOLON); }
46
46
  "::" { return next_token(state, pCOLON2); }
47
47
  "<" { return next_token(state, pLT); }
48
+ "[]" { return next_token(state, pAREF_OPR); }
48
49
  operator { return next_token(state, tOPERATOR); }
49
50
 
50
51
  number = [0-9] [0-9_]*;
@@ -68,6 +68,7 @@ static const char *RBS_TOKENTYPE_NAMES[] = {
68
68
  "tBANGIDENT",
69
69
  "tEQIDENT",
70
70
  "tQIDENT", /* Quoted identifier */
71
+ "pAREF_OPR", /* [] */
71
72
  "tOPERATOR", /* Operator identifier */
72
73
 
73
74
  "tCOMMENT",
@@ -662,6 +662,10 @@ static VALUE parse_proc_type(parserstate *state) {
662
662
  VALUE parse_record_attributes(parserstate *state) {
663
663
  VALUE hash = rb_hash_new();
664
664
 
665
+ if (state->next_token.type == pRBRACE) {
666
+ return hash;
667
+ }
668
+
665
669
  while (true) {
666
670
  VALUE key;
667
671
  VALUE type;
@@ -919,6 +923,9 @@ static VALUE parse_simple(parserstate *state) {
919
923
 
920
924
  return rbs_tuple(types, rbs_new_location(state->buffer, rg));
921
925
  }
926
+ case pAREF_OPR: {
927
+ return rbs_tuple(rb_ary_new(), rbs_new_location(state->buffer, state->current_token.range));
928
+ }
922
929
  case pLBRACE: {
923
930
  position start = state->current_token.range.start;
924
931
  VALUE fields = parse_record_attributes(state);
@@ -1376,6 +1383,7 @@ VALUE parse_method_name(parserstate *state, range *range) {
1376
1383
  case pSTAR:
1377
1384
  case pSTAR2:
1378
1385
  case pLT:
1386
+ case pAREF_OPR:
1379
1387
  case tOPERATOR:
1380
1388
  *range = state->current_token.range;
1381
1389
  return ID2SYM(INTERN_TOKEN(state, state->current_token));
@@ -68,6 +68,7 @@ module RBS
68
68
  def to_json(state = _ = nil)
69
69
  {
70
70
  member: :method_definition,
71
+ name: name,
71
72
  kind: kind,
72
73
  types: types,
73
74
  annotations: annotations,
data/lib/rbs/cli.rb CHANGED
@@ -590,7 +590,7 @@ EOU
590
590
 
591
591
  case format
592
592
  when "rbi", "rb"
593
- decls = run_prototype_file(format, args)
593
+ run_prototype_file(format, args)
594
594
  when "runtime"
595
595
  require_libs = []
596
596
  relative_libs = []
@@ -638,6 +638,9 @@ EOU
638
638
  end
639
639
 
640
640
  decls = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included).decls
641
+
642
+ writer = Writer.new(out: stdout)
643
+ writer.write decls
641
644
  else
642
645
  stdout.puts <<EOU
643
646
  Usage: rbs prototype [generator...] [args...]
@@ -653,13 +656,6 @@ Examples:
653
656
  EOU
654
657
  exit 1
655
658
  end
656
-
657
- if decls
658
- writer = Writer.new(out: stdout)
659
- writer.write decls
660
- else
661
- exit 1
662
- end
663
659
  end
664
660
 
665
661
  def run_prototype_file(format, args)
@@ -667,6 +663,11 @@ EOU
667
663
  "\n** This command does not work on this interpreter (#{RUBY_ENGINE}) **\n"
668
664
  end
669
665
 
666
+ # @type var output_dir: Pathname?
667
+ output_dir = nil
668
+ # @type var base_dir: Pathname?
669
+ base_dir = nil
670
+
670
671
  opts = OptionParser.new
671
672
  opts.banner = <<EOU
672
673
  Usage: rbs prototype #{format} [files...]
@@ -680,7 +681,21 @@ Examples:
680
681
 
681
682
  $ rbs prototype rb lib/foo.rb
682
683
  $ rbs prototype rbi sorbet/rbi/foo.rbi
684
+
685
+ You can run the tool in *batch* mode by passing `--out-dir` option.
686
+
687
+ $ rbs prototype rb --out-dir=sig lib/foo.rb
688
+ $ rbs prototype rbi --out-dir=sig/models --base-dir=app/models app/models
683
689
  EOU
690
+
691
+ opts.on("--out-dir=DIR", "Specify the path to save the generated RBS files") do |path|
692
+ output_dir = Pathname(path)
693
+ end
694
+
695
+ opts.on("--base-dir=DIR", "Specify the path to calculate the relative path to save the generated RBS files") do |path|
696
+ base_dir = Pathname(path)
697
+ end
698
+
684
699
  opts.parse!(args)
685
700
 
686
701
  unless has_parser?
@@ -693,18 +708,80 @@ EOU
693
708
  return nil
694
709
  end
695
710
 
696
- parser = case format
697
- when "rbi"
698
- Prototype::RBI.new()
699
- when "rb"
700
- Prototype::RB.new()
701
- end
702
-
703
- args.each do |file|
704
- parser.parse Pathname(file).read
711
+ new_parser = -> do
712
+ case format
713
+ when "rbi"
714
+ Prototype::RBI.new()
715
+ when "rb"
716
+ Prototype::RB.new()
717
+ end
705
718
  end
706
719
 
707
- parser.decls
720
+ input_paths = args.map {|arg| Pathname(arg) }
721
+
722
+ if output_dir
723
+ # batch mode
724
+ input_paths.each do |path|
725
+ stdout.puts "Processing `#{path}`..."
726
+ ruby_files =
727
+ if path.file?
728
+ [path]
729
+ else
730
+ path.glob("**/*.rb").sort
731
+ end
732
+
733
+ ruby_files.each do |file_path|
734
+ stdout.puts " Generating RBS for `#{file_path}`..."
735
+
736
+ relative_path =
737
+ if base_dir
738
+ file_path.relative_path_from(base_dir)
739
+ else
740
+ if top = file_path.descend.first
741
+ case
742
+ when top == Pathname("lib")
743
+ file_path.relative_path_from(top)
744
+ when top == Pathname("app")
745
+ file_path.relative_path_from(top)
746
+ else
747
+ file_path
748
+ end
749
+ else
750
+ file_path
751
+ end
752
+ end
753
+ relative_path = relative_path.cleanpath()
754
+
755
+ if relative_path.absolute? || relative_path.descend.first&.to_s == ".."
756
+ stdout.puts " ⚠️ Cannot write the RBS to outside of the output dir: `#{relative_path}`"
757
+ next
758
+ end
759
+
760
+ output_path = (output_dir + relative_path).sub_ext(".rbs")
761
+
762
+ parser = new_parser[]
763
+ parser.parse file_path.read()
764
+
765
+ stdout.puts " Writing RBS to `#{output_path}`..."
766
+
767
+ (output_path.parent).mkpath
768
+ output_path.open("w") do |io|
769
+ writer = Writer.new(out: io)
770
+ writer.write(parser.decls)
771
+ end
772
+ end
773
+ end
774
+ else
775
+ # file mode
776
+ parser = new_parser[]
777
+
778
+ input_paths.each do |file|
779
+ parser.parse file.read()
780
+ end
781
+
782
+ writer = Writer.new(out: stdout)
783
+ writer.write parser.decls
784
+ end
708
785
  end
709
786
 
710
787
  def run_vendor(args, options)
@@ -85,9 +85,14 @@ module RBS
85
85
  case node.type
86
86
  when :CLASS
87
87
  class_name, super_class, *class_body = node.children
88
+ super_class_name = const_to_name(super_class)
89
+ if super_class_name.nil?
90
+ # Give up detect super class e.g. `class Foo < Struct.new(:bar)`
91
+ super_class = nil
92
+ end
88
93
  kls = AST::Declarations::Class.new(
89
94
  name: const_to_name(class_name),
90
- super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: [], location: nil),
95
+ super_class: super_class && AST::Declarations::Class::Super.new(name: super_class_name, args: [], location: nil),
91
96
  type_params: [],
92
97
  members: [],
93
98
  annotations: [],
@@ -485,7 +490,7 @@ module RBS
485
490
  case node.type
486
491
  when :STR
487
492
  lit = node.children[0]
488
- if lit.match?(/\A[ -~]+\z/)
493
+ if lit.ascii_only?
489
494
  Types::Literal.new(literal: lit, location: nil)
490
495
  else
491
496
  BuiltinNames::String.instance_type
@@ -506,7 +511,7 @@ module RBS
506
511
  lit = node.children[0]
507
512
  case lit
508
513
  when Symbol
509
- if lit.match?(/\A[ -~]+\z/)
514
+ if lit.to_s.ascii_only?
510
515
  Types::Literal.new(literal: lit, location: nil)
511
516
  else
512
517
  BuiltinNames::Symbol.instance_type
@@ -518,15 +523,15 @@ module RBS
518
523
  Types::ClassInstance.new(name: type_name, args: [], location: nil)
519
524
  end
520
525
  when :ZLIST, :ZARRAY
521
- BuiltinNames::Array.instance_type([untyped])
526
+ BuiltinNames::Array.instance_type(untyped)
522
527
  when :LIST, :ARRAY
523
528
  elem_types = node.children.compact.map { |e| literal_to_type(e) }
524
529
  t = types_to_union_type(elem_types)
525
- BuiltinNames::Array.instance_type([t])
530
+ BuiltinNames::Array.instance_type(t)
526
531
  when :DOT2, :DOT3
527
532
  types = node.children.map { |c| literal_to_type(c) }
528
533
  type = range_element_type(types)
529
- BuiltinNames::Range.instance_type([type])
534
+ BuiltinNames::Range.instance_type(type)
530
535
  when :HASH
531
536
  list = node.children[0]
532
537
  if list
@@ -554,7 +559,7 @@ module RBS
554
559
  else
555
560
  key_type = types_to_union_type(key_types)
556
561
  value_type = types_to_union_type(value_types)
557
- BuiltinNames::Hash.instance_type([key_type, value_type])
562
+ BuiltinNames::Hash.instance_type(key_type, value_type)
558
563
  end
559
564
  when :CALL
560
565
  receiver, method_name, * = node.children
data/lib/rbs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "2.4.0"
2
+ VERSION = "2.5.0"
3
3
  end
data/schema/members.json CHANGED
@@ -8,6 +8,9 @@
8
8
  "type": "string",
9
9
  "enum": ["method_definition"]
10
10
  },
11
+ "name": {
12
+ "type": "string"
13
+ },
11
14
  "kind": {
12
15
  "enum": ["instance", "singleton", "singleton_instance"]
13
16
  },
@@ -42,7 +45,7 @@
42
45
  "enum": ["public", "private", null]
43
46
  }
44
47
  },
45
- "required": ["member", "kind", "types", "comment", "annotations", "location", "visibility"]
48
+ "required": ["member", "name", "kind", "types", "comment", "annotations", "location", "visibility"]
46
49
  },
47
50
  "variable": {
48
51
  "title": "Declaration for instance variables and class variables",
data/steep/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- activesupport (7.0.2.4)
4
+ activesupport (7.0.3)
5
5
  concurrent-ruby (~> 1.0, >= 1.0.2)
6
6
  i18n (>= 1.6, < 2)
7
7
  minitest (>= 5.1)
@@ -23,8 +23,8 @@ GEM
23
23
  rb-fsevent (0.11.1)
24
24
  rb-inotify (0.10.1)
25
25
  ffi (~> 1.0)
26
- rbs (2.3.2)
27
- steep (0.52.2)
26
+ rbs (2.4.0)
27
+ steep (1.0.0)
28
28
  activesupport (>= 5.1)
29
29
  language_server-protocol (>= 3.15, < 4.0)
30
30
  listen (~> 3.0)
@@ -46,4 +46,4 @@ DEPENDENCIES
46
46
  steep
47
47
 
48
48
  BUNDLED WITH
49
- 2.2.22
49
+ 2.3.14
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-08 00:00:00.000000000 Z
11
+ date: 2022-05-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: RBS is the language for type signatures for Ruby and standard library
14
14
  definitions.