rbs 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/Gemfile.lock +10 -10
- data/core/time.rbs +5 -5
- data/ext/rbs_extension/lexer.c +581 -574
- data/ext/rbs_extension/lexer.h +2 -1
- data/ext/rbs_extension/lexer.re +2 -1
- data/ext/rbs_extension/lexstate.c +1 -0
- data/ext/rbs_extension/parser.c +8 -0
- data/lib/rbs/ast/members.rb +1 -0
- data/lib/rbs/cli.rb +95 -18
- data/lib/rbs/prototype/rb.rb +12 -7
- data/lib/rbs/version.rb +1 -1
- data/schema/members.json +4 -1
- data/steep/Gemfile.lock +4 -4
- metadata +2 -2
data/ext/rbs_extension/lexer.h
CHANGED
@@ -69,7 +69,8 @@ enum TokenType {
|
|
69
69
|
tBANGIDENT, /* Identifiers ending with `!` */
|
70
70
|
tEQIDENT, /* Identifiers ending with `=` */
|
71
71
|
tQIDENT, /* Quoted identifier */
|
72
|
-
|
72
|
+
pAREF_OPR, /* [] */
|
73
|
+
tOPERATOR, /* Operator identifier */
|
73
74
|
|
74
75
|
tCOMMENT, /* Comment */
|
75
76
|
tLINECOMMENT, /* Comment of all line */
|
data/ext/rbs_extension/lexer.re
CHANGED
@@ -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_]*;
|
data/ext/rbs_extension/parser.c
CHANGED
@@ -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));
|
data/lib/rbs/ast/members.rb
CHANGED
data/lib/rbs/cli.rb
CHANGED
@@ -590,7 +590,7 @@ EOU
|
|
590
590
|
|
591
591
|
case format
|
592
592
|
when "rbi", "rb"
|
593
|
-
|
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
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
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
|
-
|
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)
|
data/lib/rbs/prototype/rb.rb
CHANGED
@@ -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:
|
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.
|
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.
|
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(
|
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(
|
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(
|
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(
|
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
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.
|
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.
|
27
|
-
steep (0.
|
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.
|
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
|
+
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-
|
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.
|