rbs 2.4.0 → 2.5.0

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